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 }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM