新年好(Dijkstra+dfs/全排列)

1135. 新年好 - AcWing题库

思路: 1.先预处理出1,a,b,c,d,e到其他点的单源最短路,也就是进行6次Dijkstra

2.计算以1为起点的这6个数的全排列,哪种排列方式所得距离最小,也可以使用dfs

1.Dijkstra+dfs

cpp 复制代码
#define int long long

using namespace std;

typedef pair<int,int> PII;

constexpr int N =2e5+5;
int dist[6][N];
bool st[50005];
int n,m,h[N],w[N],ne[N],e[N],idx;
int rela[N];
int ans;

void add(int a,int b,int c)
{
    e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
}

void Dijkstra(int s, int dist[])
{
    memset(dist, 0x3f, N*4);//int是4字节,所以大小就是4*N
    memset(st,0,sizeof st);
    dist[s]=0;
    priority_queue<PII,vector<PII>,greater<PII>> heap;
    heap.push({0,s});
    while(heap.size())
    {
        auto [c,t] = heap.top();heap.pop();
        if(st[t]) continue;
        st[t]=true;
        for(int i=h[t];~i;i=ne[i])
        {
            int j=e[i];
            if(dist[j]>c+w[i])
            {
                dist[j]=c+w[i];
                heap.push({dist[j],j});
            }
        }
    }
}

int dfs(int u,int num,int dis) 
{
        if (num==6)
        {
            return dis;
        }
        int ret=0x3f3f3f3f;
        for (int i=1;i<=5;i++)
        {
            if (!st[i])
            {
                st[i] = 1;
                ret = min(ret,dfs(i,num+1,dis+dist[u][rela[i]]));
                st[i] = 0;
            }
        }
        return ret;
}

void solve()
{
    cin>>n>>m;
    rela[0]=1;
    for(int i=1;i<=5;i++)
    {
      cin>>rela[i];
    }
   
    memset(h,-1,sizeof h);
    while(m--)
    {
        int a,b,c;
        cin>>a>>b>>c;
        add(a,b,c),add(b,a,c);
    }
    for(int i=0;i<=5;i++)
    {
      Dijkstra(rela[i],dist[i]);
    }
    memset(st,false,sizeof st);
    cout<<dfs(0,1,0);
}

int32_t main()
{
   int t;//cin>>t;
   t=1;
   while(t--) solve();
}

2.Dijkstra+全排列

cpp 复制代码
#define int long long

using namespace std;

typedef pair<int,int> PII;

constexpr int N =2e5+5;
int dist[6][N];
bool st[50005];
int n,m,h[N],w[N],ne[N],e[N],idx;
int rela[N],order[6];
int ans;

void add(int a,int b,int c)
{
    e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
}

void Dijkstra(int s, int dist[])
{
    memset(st,0,sizeof st);
    dist[s]=0;
    priority_queue<PII,vector<PII>,greater<PII>> heap;
    heap.push({0,s});
    while(heap.size())
    {
        auto [c,t] = heap.top();heap.pop();
        if(st[t]) continue;
        st[t]=true;
        for(int i=h[t];~i;i=ne[i])
        {
            int j=e[i];
            if(dist[j]>c+w[i])
            {
                dist[j]=c+w[i];
                heap.push({dist[j],j});
            }
        }
    }
}


void solve()
{
    memset(dist,0x3f,sizeof dist);
    cin>>n>>m;
    order[0]=0;rela[0]=1;
    for(int i=1;i<=5;i++)
    {
        order[i]=i;
      cin>>rela[i];
    }
   
    memset(h,-1,sizeof h);
    while(m--)
    {
        int a,b,c;
        cin>>a>>b>>c;
        add(a,b,c),add(b,a,c);
    }
    for(int i=0;i<=5;i++)
    {
      Dijkstra(rela[i],dist[i]);
    }
    memset(st,false,sizeof st);
    ans=0x3f3f3f3f;
    do{
        if(order[0]!=0) break;
        int sum=dist[0][rela[order[1]]];
        for(int i=1;i+1<=5;i++)
            sum+=dist[order[i]][rela[order[i+1]]];
        ans=min(ans,sum);
     }while(next_permutation(order,order+6));
    cout<<ans;
}

int32_t main()
{
   int t;//cin>>t;
   t=1;
   while(t--) solve();
}
相关推荐
汉克老师1 小时前
GESP2024年3月认证C++六级( 第三部分编程题(1)游戏)
c++·学习·算法·游戏·动态规划·gesp6级
闻缺陷则喜何志丹1 小时前
【C++图论】2685. 统计完全连通分量的数量|1769
c++·算法·力扣·图论·数量·完全·连通分量
利刃大大2 小时前
【二叉树深搜】二叉搜索树中第K小的元素 && 二叉树的所有路径
c++·算法·二叉树·深度优先·dfs
CaptainDrake2 小时前
力扣 Hot 100 题解 (js版)更新ing
javascript·算法·leetcode
一缕叶2 小时前
洛谷P9420 [蓝桥杯 2023 国 B] 子 2023 / 双子数
算法·蓝桥杯
甜甜向上呀2 小时前
【数据结构】空间复杂度
数据结构·算法
Great Bruce Young3 小时前
GPS信号生成:C/A码序列生成【MATLAB实现】
算法·matlab·自动驾驶·信息与通信·信号处理
Mryan20053 小时前
LeetCode | 不同路径
数据结构·c++·算法·leetcode
qy发大财3 小时前
验证二叉搜索树(力扣98)
数据结构·算法·leetcode·职场和发展
人类群星闪耀时4 小时前
用深度学习优化供应链管理:让算法成为商业决策的引擎
人工智能·深度学习·算法