http://acm.hdu.edu.cn/showproblem.php?pid=1102
最小生成树(模板题)
3
0 990 692
990 0 179
692 179 0
1
1 2
一共3个村子,下面是第i行j列 i村子和j村子之间建路需要的距离
下面是一个k
代表有k条路已经修好了,1村子和2村子之间以修路
1 #include<iostream> 2 #include<math.h> 3 #include<string.h> 4 #include<stdlib.h> 5 #include<stdio.h> 6 using namespace std; 7 const int N=5005; 8 struct stu{ 9 int u; 10 int v; 11 int w; 12 }p[N]; 13 int q[105][105]; 14 int father[N]; 15 int n,m; 16 int cmp(const void *a,const void *b) 17 { 18 return (*(struct stu*)a).w > (*(struct stu*)b).w ?1:-1; 19 } 20 int find(int x) 21 { 22 if(father[x]!=x) 23 father[x]=find(father[x]); 24 return father[x]; 25 } 26 int make(int a,int b) 27 { 28 int h=0; 29 int f1=find(a); 30 int f2=find(b); 31 if(f1>f2) 32 { 33 father[f1]=f2; 34 h=1; 35 } 36 else if(f1<f2) 37 { 38 father[f2]=f1; 39 h=1; 40 } 41 return h; 42 } 43 int kruskal() 44 { 45 int cnt=0; 46 int s=0; 47 for(int i=0;i<m;i++) 48 { 49 if(make(p[i].u,p[i].v)) 50 { 51 cnt++; 52 s+=p[i].w; 53 } 54 if(cnt==n-1) 55 return s; 56 } 57 return s; 58 } 59 60 int main() 61 { 62 //freopen("in.txt","r",stdin); 63 int k; 64 while(~scanf("%d",&n)) 65 { 66 for(int i=1;i<=n;i++) 67 father[i]=i; 68 for(int i=1;i<=n;i++) 69 { 70 for(int j=1;j<=n;j++) 71 { 72 scanf("%d",&q[i][j]); 73 } 74 } 75 scanf("%d",&k); 76 int a,b; 77 while(k--) 78 { 79 scanf("%d%d",&a,&b); 80 q[a][b]=0;//已经建路,清0 81 } 82 m=0; 83 for(int i=1;i<=n;i++) 84 { 85 for(int j=i+1;j<=n;j++) 86 { 87 p[m].u=i; 88 p[m].v=j; 89 p[m++].w=q[i][j]; 90 } 91 } 92 qsort(p,m,sizeof(struct stu),cmp); 93 // for(int i=0;i<m;i++) 94 // { 95 // printf("%d %d %d\n",p[i].u,p[i].v,p[i].w); 96 // } 97 printf("%d\n",kruskal()); 98 99 } 100 return 0; 101 }
时间: 2024-11-07 13:10:13