ZOJ2048最小生成树Kruskal算法
此算法在POJ上跑超时了,用了3s+;具体的思路和Prim算法一样
View Code
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #define N 755 5 6 int rank[N],father[N]; 7 int dis_sum, x[N], y[N]; 8 typedef struct 9 { 10 int x, y; 11 int w; 12 }edge; 13 edge e[N*N]; 14 15 int cmp(const void *a,const void *b) 16 { 17 return (*(edge *)a).w > (*(edge *)b).w ? 1 : -1; 18 } 19 20 int Make_set(int x) 21 { 22 father[x] = x; 23 rank[x] = 0; 24 } 25 26 int Find_set(int x) 27 { 28 if(x != father[x] ) 29 father[x] = Find_set(father[x]); 30 return father[x]; 31 } 32 void Link(int x,int y,int w) 33 { 34 if(rank[x] > rank[y]) 35 father[y] = x; 36 else 37 { 38 father[x] = y; 39 if(rank[x]==rank[y]) rank[y]++; 40 } 41 dis_sum += w; 42 } 43 44 void Kruskal(int n,int m) 45 { 46 int i,x,y; 47 qsort(e,m,sizeof(edge),cmp); 48 dis_sum = 0; 49 for(i=1; i<=m; i++) 50 { 51 x = Find_set(e[i].x); 52 y = Find_set(e[i].y); 53 if(x != y) 54 { Link(x,y,e[i].w); 55 printf("%d %d\n",e[i].x,e[i].y); 56 } 57 } 58 } 59 60 int main() 61 { 62 int i, j, towns, k; 63 int n, a, b,ncases; 64 65 scanf("%d",&ncases); 66 while( ncases-- ) 67 { 68 scanf("%d",&towns); 69 for(i=1; i<=towns; i++) 70 { 71 scanf("%d%d",&x[i],&y[i]); 72 Make_set(i); 73 } 74 k = 1; 75 for(i=1; i<=towns; i++) 76 for(j=1; j<=towns; j++) 77 { 78 e[k].x = i; 79 e[k].y = j; 80 e[k].w = (x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]); 81 k++; 82 } 83 84 scanf("%d",&n); 85 for(i=1; i<=n; i++) 86 { 87 scanf("%d%d",&a,&b); 88 a = Find_set(a); 89 b = Find_set(b); 90 Link(a,b,0); 91 } 92 Kruskal(towns,k-1); 93 if( ncases) printf("\n"); 94 } 95 return 0; 96 }