ZOJ 1542 Network(Kruskal)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=542
找最长路最短的生成树,可以用kruskal算法求最小生成树,记录可加入的第n-1条边就行了,主要是并查集的应用,按lrj书上并查集的写法,只有一句话就可以表示。
代码如下:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 5 #define N_MAX 1010 6 #define M_MAX 15010 7 #define INF 1000006 8 9 typedef struct Edge 10 { 11 int u,v,w; 12 }Edge; 13 14 Edge e[M_MAX]; 15 int fa[N_MAX],ans[N_MAX]; 16 int n,m; 17 18 int find(int x) {return fa[x]==x?x:(fa[x]=find(fa[x]));} 19 20 int cmp(const void *_a,const void *_b) 21 { 22 Edge *a=(Edge *)_a; 23 Edge *b=(Edge *)_b; 24 if(a->w!=b->w) return a->w>b->w; 25 else if(a->u!=b->u) return a->u>b->u; 26 else return a->v>b->v; 27 } 28 29 int main() 30 { 31 int i,count,t; 32 while(scanf("%d%d",&n,&m)!=EOF) 33 { 34 count=0; 35 for(i=0;i<=n;i++) 36 fa[i]=i; 37 for(i=0;i<m;i++) 38 { 39 scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w); 40 } 41 qsort(e,m,sizeof(Edge),cmp); 42 for(i=0;i<m;i++) 43 { 44 if(find(e[i].u)==find(e[i].v)) continue; 45 else 46 { 47 t=find(e[i].u); 48 fa[t]=find(e[i].v); 49 ans[count++]=i; 50 if(count==n-1) break; 51 } 52 53 } 54 printf("%d\n",e[ans[count-1]].w); 55 printf("%d\n",count); 56 for(i=0;i<count;i++) 57 { 58 printf("%d %d\n",e[ans[i]].u,e[ans[i]].v); 59 } 60 } 61 return 0; 62 }