Codeup墓地-问题 A: 还是畅通工程
生活随笔
收集整理的這篇文章主要介紹了
Codeup墓地-问题 A: 还是畅通工程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目描述
? ? ? ? 某省調查鄉村交通狀況,得到的統計表中列出了任意兩村莊間的距離。省政府“暢通工程”的目標是使全省任何兩個村莊間都可以實現公路交通(但不一定有直接的公路相連,只要能間接通過公路可達即可),并要求鋪設的公路總長度為最小。請計算最小的公路總長度。
輸入
? ? ? ? 測試輸入包含若干測試用例。每個測試用例的第1行給出村莊數目N ( < 100 );隨后的N(N-1)/2行對應村莊間的距離,每行給出一對正整數,分別是兩個村莊的編號,以及此兩村莊間的距離。為簡單起見,村莊從1到N編號。
? ? ? ? 當N為0時,輸入結束,該用例不被處理。
輸出
? ? ? ? 對每個測試用例,在1行里輸出最小的公路總長度。
樣例輸入
8 1 2 42 1 3 68 1 4 35 1 5 1 1 6 70 1 7 25 1 8 79 2 3 59 2 4 63 2 5 65 2 6 6 2 7 46 2 8 82 3 4 28 3 5 62 3 6 92 3 7 96 3 8 43 4 5 28 4 6 37 4 7 92 4 8 5 5 6 3 5 7 54 5 8 93 6 7 83 6 8 22 7 8 17 0樣例輸出
82?
第一版:時間超限
#include <iostream> #include <algorithm> #include <vector>using namespace std;const int maxn = 100; const int inf = 1000000000;int n; //村莊數目int G[maxn][maxn]; int d[maxn]; bool vis[maxn] = {false};int prim(int s) {fill(d, d+maxn, inf);d[s] = 0;int ans = 0;for(int i = 1; i <= n; i++){int u = -1, min = inf;for(int j = 1; j <= n; j++){if(vis[j] == false && d[j] < min){u = j;min = d[j];}}if(u == -1) return -1;vis[u] = true;ans += d[u];for(int v = 1; v <= n; v++){if(vis[v] == false && G[u][v] != inf && G[u][v] < d[v]){d[v] = G[u][v];}}}return ans; } int main() {while(scanf("%d", &n) != 0){ // if(n == 0) break;int m = n * (n-1) / 2;fill(G[0], G[0]+maxn*maxn, inf); //初始化for(int i = 1; i <= m; i++){int a, b, c;scanf("%d%d%d", &a, &b, &c);G[a][b] = c;G[b][a] = c;}int ans = prim(1);if(ans != 0)printf("%d\n", ans);}return 0; }?第二版:運行錯誤
提示:數組越界。但是我看了一圈沒發現...有看出的同仁請告知,萬分感謝!
#include <iostream> #include <algorithm> #include <vector>using namespace std;const int maxn = 100+10; const int inf = 1000000000;int a; //村莊數目//kruskal struct edge {int u, v, dis; }E[maxn];int father[maxn]; int find_father(int x) {int a = x;while(x != father[x]){x = father[x];}while(a != father[a]){int z = a;a = father[a];father[z] = x;}return x; }bool cmp(edge a, edge b) {return a.dis < b.dis; }int kruskal(int n, int m) {int ans = 0, num_edge = 0;for(int i = 1; i <= n; i++){father[i] = i;}sort(E, E+m+1, cmp);for(int i = 0; i < m; i++){int fa = find_father(E[i].u);int fb = find_father(E[i].v);if(fa != fb){father[fa] = fb;ans += E[i].dis;num_edge++;if(num_edge == n - 1) break;}}if(num_edge != n - 1){return -1;}else return ans; }int main() {while(scanf("%d", &a) != 0){int b = a * (a-1) / 2;for(int i = 0; i < b; i++){scanf("%d%d%d", &E[i].u, &E[i].v, &E[i].dis);}int ans = kruskal(a, b);printf("%d\n", ans);}return 0; }?
AC代碼:
終于AC了,發帖求助的。真是犯了低級錯誤。邊數為N(N-1)/2,自己開的maxn太小,所以超了!流淚,我太菜雞惹...
#include <iostream> #include <algorithm> #include <vector>using namespace std;const int maxn = 5010; const int inf = 1000000000;int a; //村莊數目//kruskal struct edge {int u, v, dis; }E[maxn];int father[110]; int find_father(int x) {int a = x;while(x != father[x]){x = father[x];}while(a != father[a]){int z = a;a = father[a];father[z] = x;}return x; }bool cmp(edge a, edge b) {return a.dis < b.dis; }int kruskal(int n, int m) {int ans = 0, num_edge = 0;for(int i = 1; i <= n; i++){father[i] = i;}sort(E, E+m, cmp);for(int i = 0; i < m; i++){int fa = find_father(E[i].u);int fb = find_father(E[i].v);if(fa != fb){father[fa] = fb;ans += E[i].dis;num_edge++;if(num_edge == n - 1) break;}}if(num_edge != n - 1){return -1;}else return ans; }int main() {while(scanf("%d", &a)&& a){int b = a * (a-1) / 2;for(int i = 0; i < b; i++){scanf("%d%d%d", &E[i].u, &E[i].v, &E[i].dis);}int ans = kruskal(a, b);printf("%d\n", ans);}return 0; }?
總結
以上是生活随笔為你收集整理的Codeup墓地-问题 A: 还是畅通工程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Codeup墓地-问题 D: 最短路径
- 下一篇: Codeup-问题 C: 畅通工程