新年好(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();
}
相关推荐
wuweijianlove12 小时前
算法中的记忆化思想与重复子问题优化的技术5
算法
小江的记录本13 小时前
【JVM虚拟机】垃圾回收GC:垃圾判定算法:引用计数法、可达性分析算法(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·算法·spring·面试
Hello.Reader13 小时前
算法基础(十四)—— 随机化快速排序为什么平均表现很好
算法
吴可可12313 小时前
Teigha中OdGe几何库详解及C#使用
算法
爱喝水的鱼丶13 小时前
SAP-ABAP:变量、常量、结构与内表声明(10篇博客合集) 第六篇:ABAP 7.40+新特性:声明语法的简化写法与兼容注意事项
运维·服务器·开发语言·学习·算法·sap·abap
国科安芯13 小时前
AS32S601商业航天级抗辐照MCU芯片:架构设计与技术特性研究
单片机·嵌入式硬件·算法·安全·架构·risc-v
菜菜的顾清寒14 小时前
力扣HOT100(34)图论-岛屿数量
算法·leetcode·图论
名字不好奇14 小时前
大模型的思考模式:它真的在“想“吗?
人工智能·算法
Run_Teenage14 小时前
算法模板:输入输出,并查集
java·开发语言·算法
高一学习c++会秃头吗14 小时前
操作系统内存块分配算法
算法