最短路变种-交通规划

题目大意:

  G国国王来中国参观后,被中国的高速铁路深深的震撼,决定为自己的国家也建设一个高速铁路系统。
  建设高速铁路投入非常大,为了节约建设成本,G国国王决定不新建铁路,而是将已有的铁路改造成高速铁路。现在,请你为G国国王提供一个方案,将现有的一部分铁路改造成高速铁路,使得任何两个城市间都可以通过高速铁路到达,而且从所有城市乘坐高速铁路到首都的最短路程和原来一样长。请你告诉G国国王在这些条件下最少要改造多长的铁路。

思路:

  这个题是一个最短路问题,要求在最短路一样的条件下保证每次必要的花费是最小的,所以每次维护一个cost数组用来记录最短路的条件下的最小花费迭代更新一下就行了

代码:

#include <iostream>
#include <cstring>
#include <map>
using namespace std;
const int N = 1e4+10;
const int M = 2e5+10;
int h[N],ne[M],to[M],cap[M],idx=0;
int dis[N],cost[N],vi[N];
void add(int a,int b,int c){
    ne[idx]=h[a];
    to[idx]=b;
    cap[idx]=c;
    h[a]=idx++;
}

void djs(int u,int n){
    vi[u]=1;
    memset(dis,0x3f,sizeof dis);
    dis[u]=0;
    for(int i=h[u];~i;i=ne[i]){
        int v=to[i];
        if(!vi[v]){
            dis[v]=cap[i];
            cost[v]=cap[i];
        }
    }
    for(int i=1;i<=n-1;i++){
        int minid=-1;
        int minc=0x3f3f3f3f;
        for(int j=1;j<=n;j++){
            if(!vi[j]){
                if(minc>dis[j]){
                    minc=dis[j];
                    minid=j;
                }
            }
        }
        if(minid==-1)break;
        vi[minid]=1;
        for(int j=h[minid];~j;j=ne[j]){
            int v=to[j];
            if(!vi[v]){
                if(dis[v]>dis[minid]+cap[j]){
                    dis[v]=dis[minid]+cap[j];
                    cost[v]=cap[j];
                }
                else if(dis[v]==dis[minid]+cap[j]){
                    if(cost[v]>cap[j]){
                        cost[v]=cap[j];
                    }
                }
            }
        }
    }
}

int main(){
    int n,m;
    cin>>n>>m;
    memset(h,-1,sizeof h);
    for(int i=0;i<m;i++){
        int a,b,c;
        cin>>a>>b>>c;
        add(a,b,c);
        add(b,a,c);
    }
    djs(1,n);
    int res=0;
    for(int i=2;i<=n;i++){
        res+=cost[i];
    }
    cout<<res<<endl;
}

 

posted @ 2020-08-23 16:18  kstranger  阅读(216)  评论(0)    收藏  举报