zoukankan      html  css  js  c++  java
  • AcWing1135新年好(dfs+dijkstra)

    题目地址https://www.acwing.com/problem/content/description/1137/

    题目描述

    重庆城里有 n 个车站,mm条 双向 公路连接其中的某些车站。

    每两个车站最多用一条公路连接,从任何一个车站出发都可以经过一条或者多条公路到达其他车站,但不同的路径需要花费的时间可能不同。

    在一条路径上花费的时间等于路径上所有公路需要的时间之和。

    佳佳的家在车站 1,他有五个亲戚,分别住在车站 a,b,c,d,e

    过年了,他需要从自己的家出发,拜访每个亲戚(顺序任意),给他们送去节日的祝福。

    怎样走,才需要最少的时间?

    输入格式

    第一行:包含两个整数 n,m,分别表示车站数目和公路数目。

    第二行:包含五个整数 a,b,c,d,e分别表示五个亲戚所在车站编号。

    以下 m 行,每行三个整数 x,y,t表示公路连接的两个车站编号和时间。

    输出格式

    输出仅一行,包含一个整数 T,表示最少的总时间。

    数据范围

    1n50000
    1m1e5
    1<a,b,c,d,en
    1x,yn
    1t100

    题解:这道题是dfs+dijkstra,我们可以分别求出1,a,b,c,d,e到其余点的最段距离,那么剩下的,只需要枚举这六个点的先后顺序,枚举的时候,因为之前dijkstra将所有的距离都算出来了,那么这一步枚举的复杂度也只是O(5!)

    AC代码

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    using namespace std;
    const int N=50010,M=1e5+10;
    #define P pair<int,int> 
    struct node{
        int from,to,next,dis;
    }edge[M*2];
    int head[N],cnt,dis[6][N],fl[6]={0},ans=0x3f3f3f3f,a[6];
    
    void dfs(int x,int s,int dep){
        if(dep==5){//只有最后一次才能回到1
            ans=min(ans,s);
            return ;
        }
        for(int i=1;i<=5;i++){
            if(!fl[i]) {
                fl[i]=1;
                dfs(i,s+dis[x][a[i]],dep+1);
                fl[i]=0;
            }
        }
        return ;
    }
    
    void addedge(int u,int v,int w){
        cnt++;
        edge[cnt].from=u;
        edge[cnt].to=v;
        edge[cnt].dis=w;
        edge[cnt].next=head[u];
        head[u]=cnt;
    }
    
    
    void dijkstra(int s,int k){
        memset(dis[k],0x3f,sizeof(dis[k]));
        int p[N]={0};
        priority_queue<P,vector<P>,greater<P> >q;
        q.push(make_pair(0,s));
        dis[k][s]=0;
        while(!q.empty()){
            P now=q.top();q.pop();
            if(p[now.second]) continue;
            p[now.second]=1;
            int w=now.first,v=now.second;
            for(int i=head[v];~i;i=edge[i].next){
                if(dis[k][edge[i].to]>dis[k][edge[i].from]+edge[i].dis){
                    dis[k][edge[i].to]=dis[k][edge[i].from]+edge[i].dis;
                    q.push(make_pair(dis[k][edge[i].to],edge[i].to));
                }
            }
        }
    }
    
    int main(){
        int n,m;cin>>n>>m;
        a[0]=1;
        memset(head,-1,sizeof(head));
        for(int i=1;i<=5;i++) cin>>a[i];
        for(int i=1,u,v,w;i<=m;i++){
            scanf("%d%d%d",&u,&v,&w);
            addedge(u,v,w);
            addedge(v,u,w);
        }
        for(int i=0;i<=5;i++){
            dijkstra(a[i],i);
        }
        dfs(0,0,0);
        cout<<ans;
        return 0;
    }

    写于:2020/9/5 14:51


    作者:孙建钊
    出处:http://www.cnblogs.com/sunjianzhao/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    非父子组件通信
    vue中的导航守卫
    vue中做出购物车的功能
    vuex初使用(写的当然是最简单的应用啦)
    封装了一个电商放大镜移入放大的功能,适用于VUE
    moment.js插件的简单上手使用
    Vue中如何将数据传递到下一个页面(超级简单哒)
    java Math
    java Arrays
    java static
  • 原文地址:https://www.cnblogs.com/sunjianzhao/p/13618195.html
Copyright © 2011-2022 走看看