新年好(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();
}
相关推荐
月明长歌22 分钟前
【码道初阶】一道经典简单题:多数元素(LeetCode 169)|Boyer-Moore 投票算法详解
算法·leetcode·职场和发展
wadesir27 分钟前
C语言模块化设计入门指南(从零开始构建清晰可维护的C程序)
c语言·开发语言·算法
t1987512830 分钟前
MATLAB水声信道仿真程序
开发语言·算法·matlab
云和恩墨1 小时前
AI驱动的Oracle SQL优化:从经验依赖到智能协同的三大价值
人工智能·sql·oracle·深度优先·dba
CoderYanger2 小时前
动态规划算法-简单多状态dp问题:15.买卖股票的最佳时机含冷冻期
开发语言·算法·leetcode·动态规划·1024程序员节
Xの哲學2 小时前
Linux RTC深度剖析:从硬件原理到驱动实践
linux·服务器·算法·架构·边缘计算
狐572 小时前
2025-12-04-牛客刷题笔记-25_12-4-质数统计
笔记·算法
小O的算法实验室2 小时前
2024年IEEE IOTJ SCI2区TOP,基于混合算法的水下物联网多AUV未知环境全覆盖搜索方法,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
洲星河ZXH2 小时前
Java,比较器
java·开发语言·算法
CoderYanger2 小时前
递归、搜索与回溯-FloodFill:33.太平洋大西洋水流问题
java·算法·leetcode·1024程序员节