HDU 1233 prim kruskal最小生成树模板题
Description
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。 当N为0时,输入结束,该用例不被处理。
Output
对每个测试用例,在1行里输出最小的公路总长度。
Sample Input
3 1 2 1 1 3 2 2 3 4 4 1 2 1 1 3 4 1 4 1 2 3 3 2 4 2 3 4 5 0
Sample Output
3 5
Hint
Hint Huge input, scanf is recommended.
第一道最小生成树的题目,以此题作为模板。
Prim算法
1 #include <iostream> 2 using namespace std; 3 #define INF 999999999 4 5 int map[101][101],visit[101],dis[101],N; 6 int prim() 7 { 8 for(int i = 2; i <= N; i++) 9 { 10 visit[i] = 0; 11 dis[i] = map[i][1]; 12 } 13 visit[1] = 1; 14 int sum = 0; 15 for(int i = 1; i <= N-1; i++) 16 { 17 int temp = INF,pos; 18 for(int j = 1; j <= N; j++) 19 { 20 if(!visit[j] && dis[j] < temp) 21 { 22 temp = dis[j]; 23 pos = j; 24 } 25 } 26 visit[pos] = 1; 27 sum += dis[pos]; 28 for(int j = 1; j <= N; j++) 29 { 30 if(!visit[j] && dis[j] > map[pos][j] && map[pos][j]!= INF) 31 dis[j] = map[pos][j]; 32 } 33 } 34 return sum; 35 } 36 37 int main() 38 { 39 while(scanf("%d",&N),N) 40 { 41 int u,v,w; 42 for(int i = 1; i <= N; i++) 43 dis[i] = INF; 44 for(int i = 1; i <= (N*(N-1))/2; i++) 45 { 46 scanf("%d%d%d",&u,&v,&w); 47 map[u][v] = map[v][u] = w; 48 } 49 cout<<prim()<<endl; 50 } 51 }
Kruskal算法
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #define maxn 103 5 using namespace std; 6 7 int father[maxn]; 8 struct edges 9 { 10 int pre; 11 int suc; 12 int w; 13 }edge[5000]; 14 15 int cmp(edges x, edges y) 16 { 17 return (x.w < y.w)?1:0; 18 } 19 int find(int x) 20 { 21 if(father[x] == x)return x; 22 return father[x] = find(father[x]); 23 } 24 int kruskal(int n,int es) 25 { 26 for(int i = 1; i <= n; i++) 27 { 28 father[i] = i; 29 } 30 sort(edge+1,edge+1+es,cmp); 31 int sum = 0; 32 for(int i = 1; i <= es; i++) 33 { 34 int fx = find(edge[i].pre),fy = find(edge[i].suc); 35 if(fx != fy) 36 { 37 father[fx] = fy; 38 sum += edge[i].w; 39 } 40 } 41 return sum; 42 } 43 int main() 44 { 45 int n,es; 46 while(scanf("%d",&n),n) 47 { 48 es = (n*(n-1))/2; 49 for(int i = 1; i <= es; i++) 50 { 51 scanf("%d%d%d",&edge[i].pre,&edge[i].suc,&edge[i].w); 52 } 53 int ans = kruskal(n,es); 54 printf("%d\n",ans); 55 } 56 57 }