poj2421:http://poj.org/problem?id=2421
题意:这一题也是最小生成树,不过它要求修的路在下面还有一行是已经修的路所以将其权值赋值为零。题目给的数值的意思是每个点离其他点的距离
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdio> 5 #include<cmath> 6 using namespace std; 7 int n,q,num,pa[102],cnt,sum; 8 int g[101][101],a,b; 9 struct Node{ 10 int u; 11 int v; 12 int w; 13 bool operator<(const Node &a)const{ 14 return w<a.w; 15 } 16 17 }edge[5000]; 18 void UFset(){ 19 for(int i=1;i<=n;i++) 20 pa[i]=-1; 21 } 22 int Find(int x){ 23 int s; 24 for(s=x;pa[s]>=0;s=pa[s]); 25 while(s!=x){ 26 int temp=pa[x]; 27 pa[x]=s; 28 x=temp; 29 } 30 return s; 31 } 32 void Union(int R1,int R2){ 33 int r1=Find(R1); 34 int r2=Find(R2); 35 int temp=pa[r1]+pa[r2]; 36 if(pa[r1]>pa[r2]){ 37 pa[r1]=r2; 38 pa[r2]=temp; 39 } 40 else{ 41 pa[r2]=r1; 42 pa[r1]=temp; 43 } 44 } 45 void kruska(){ 46 UFset(); 47 num=0;sum=0; 48 for(int i=1;i<cnt;i++){ 49 int u=edge[i].u; 50 int v=edge[i].v; 51 if(Find(u)!=Find(v)){ 52 num++; 53 sum+=edge[i].w; 54 Union(u,v); 55 } 56 if(num>=n-1)break; 57 } 58 printf("%d ",sum); 59 } 60 int main(){ 61 scanf("%d",&n); 62 for(int i=1;i<=n;i++) 63 for(int j=1;j<=n;j++) 64 scanf("%d",&g[i][j]); 65 scanf("%d",&q); 66 for(int i=1;i<=q;i++){ 67 scanf("%d%d",&a,&b); 68 g[a][b]=g[b][a]=0; 69 } 70 cnt=1; 71 for(int i=1;i<=n;i++) 72 for(int j=i+1;j<=n;j++){ 73 edge[cnt].u=i;edge[cnt].v=j; 74 edge[cnt++].w=g[i][j]; 75 } 76 sort(edge+1,edge+cnt); 77 kruska(); 78 79 }