标签:
Description
Input
Output
Sample Input
Sample Output
Hint
Hint Huge input, scanf is recommended.
中文题,还是最小生成树问题,找最小边权值和,联通所有村庄
#include<iostream> #include<vector> #include<queue> using namespace std; #define INF 0xfffffff #define N 110 int n, G[N][N], vis[N], dist[N]; // dist数组存目前下标联通树上所需最小边权值即距离最小 int prim(int s) { vis[s] = 1; // 把s点挂树上,最开始可以任取一点 dist[s] = 0; // 自己把自己挂树上,不需要和谁联通,所以距离是0 int ans = 0; // ans存目前公路总长度 for(int i = 1; i <= n; i++) dist[i] = G[s][i]; // 因为当前只有s点在树上,所以i点挂树上的距离等于i点与s点的距离 for(int i = 1; i < n; i++) // 因为总共有n个村庄,所以只需要n-1条路 { int index, Min = INF; for(int j = 1; j <= n; j++) { if(!vis[j] && dist[j] < Min) Min = dist[j], index = j; // 寻找目前挂树上的最小距离 } vis[index] = 1; // 把找到的挂树上最小距离的点置为1,表示已经在树上,已经联通 ans += Min; // 把最小距离加入ans for(int j = 1; j <= n; j++) { if(!vis[j] && dist[j] >= G[index][j]) // 用当前点去更新它所连接的点挂树上的距离(前提比之前挂树上的距离短 dist[j] = G[index][j]; } } return ans; } int main() { int a, b, c; while(cin >> n, n) { for(int i = 0; i <= n; i++) { vis[i] = 0; dist[i] = INF; for(int j = 0; j <= n; j++) G[i][j] = G[j][i] = INF; G[i][i] = 0; } // 初始化 for(int i = 0; i < n*(n-1)/2; i++) { cin >> a >> b >> c; G[a][b] = G[b][a] = c; } int ans = prim(1); cout << ans << endl; } return 0; }
标签:
原文地址:http://www.cnblogs.com/Tinamei/p/4679263.html