CCF 201609-4 交通规划
问题描述
试题编号: | 201609-4 |
试题名称: | 交通规划 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: |
问题描述
G国国王来中国参观后,被中国的高速铁路深深的震撼,决定为自己的国家也建设一个高速铁路系统。
建设高速铁路投入非常大,为了节约建设成本,G国国王决定不新建铁路,而是将已有的铁路改造成高速铁路。现在,请你为G国国王提供一个方案,将现有的一部分铁路改造成高速铁路,使得任何两个城市间都可以通过高速铁路到达,而且从所有城市乘坐高速铁路到首都的最短路程和原来一样长。请你告诉G国国王在这些条件下最少要改造多长的铁路。 输入格式
输入的第一行包含两个整数n, m,分别表示G国城市的数量和城市间铁路的数量。所有的城市由1到n编号,首都为1号。
接下来m行,每行三个整数a, b, c,表示城市a和城市b之间有一条长度为c的双向铁路。这条铁路不会经过a和b以外的城市。 输出格式
输出一行,表示在满足条件的情况下最少要改造的铁路长度。
样例输入
4 5
1 2 4 1 3 5 2 3 2 2 4 3 3 4 2 样例输出
11
评测用例规模与约定
对于20%的评测用例,1 ≤ n ≤ 10,1 ≤ m ≤ 50;
对于50%的评测用例,1 ≤ n ≤ 100,1 ≤ m ≤ 5000; 对于80%的评测用例,1 ≤ n ≤ 1000,1 ≤ m ≤ 50000; 对于100%的评测用例,1 ≤ n ≤ 10000,1 ≤ m ≤ 100000,1 ≤ a, b ≤ n,1 ≤ c ≤ 1000。输入保证每个城市都可以通过铁路达到首都。 |
求解思路:
要使“从所有城市乘坐高速铁路到首都的最短路程和原来一样长”,容易想到从首都结点开始做单源最短路,修建的高速铁路一定在这些最短路上。
如果把每个结点到首都的最短路径上的边都修建成高速铁路,则显然任何两个城市间都可以以首都作为中继结点,通过高速铁路互相到达。
如果同时存在多条最短路径,应该选择扩展时用到的边距离最小的那一条。
很显然,如果利用dijkstra算法从1结点开始往外扩展,每扩展一个结点刚好就要多修一条高速铁路,因此在做求解最短路时,可以记录下每个结点扩展时所需要多修建的这条高速铁路的长度,在扩展时遇到有多种可能的最短路情况时,记录下边权最小的一个。
代码如下:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int MAX=10005; 5 const int INF=1e9; 6 int n,m; 7 8 struct HeapNode 9 { 10 int d,u; 11 bool operator<(const HeapNode& r)const 12 { 13 return d>r.d; 14 } 15 }; 16 17 struct Edge 18 { 19 int to,dis; 20 }; 21 22 vector<Edge>G[MAX]; 23 int d[MAX]; 24 bool vis[MAX]; 25 26 int cost [MAX]; 27 void dijkstra(int s) 28 { 29 priority_queue<HeapNode>Q; 30 for(int i=1;i<=n;i++) 31 d[i]=cost[s]=INF; 32 d[s]=cost[s]=0; 33 memset(vis,0,sizeof vis); 34 35 Q.push({0,s}); 36 37 while(!Q.empty()) 38 { 39 HeapNode x=Q.top(); 40 Q.pop(); 41 42 int u=x.u; 43 44 if(vis[u]) 45 continue; 46 vis[u]=true; 47 48 for(int i=0;i<G[u].size();i++) 49 { 50 Edge& e=G[u][i]; 51 if(d[e.to]>d[u]+e.dis) 52 { 53 d[e.to]=d[u]+e.dis; 54 Q.push({d[e.to],e.to}); 55 cost[e.to]=e.dis; 56 } 57 //记录下边权最小的一个 58 if(d[e.to]==d[u]+e.dis&&cost[e.to]>e.dis) 59 cost[e.to]=e.dis; 60 } 61 } 62 } 63 64 int main() 65 { 66 scanf("%d%d",&n,&m); 67 for(int i=0;i<m;i++) 68 { 69 int a,b,c; 70 scanf("%d%d%d",&a,&b,&c); 71 G[a].push_back({b,c}); 72 G[b].push_back({a,c}); 73 } 74 75 dijkstra(1); 76 int ans=0; 77 for(int i=2;i<=n;i++) 78 ans+=cost[i]; 79 80 printf("%d\n",ans); 81 82 return 0; 83 }