zoj 3204 最小生成树,输出字典序最小的解
注意排序即可
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 #define for0n for(i=0;i<n;i++) 9 #define for1n for(i=1;i<=n;i++) 10 #define for0m for(i=0;i<m;i++) 11 #define for1m for(i=1;i<=m;i++) 12 #define cl(a) memset(a,0,sizeof(a)) 13 #define w12 while(scanf("%d%d",&n,&m)!=EOF) 14 #define s12 scanf("%d%d",&n,&m); 15 #define sa scanf("%d",a[i]); 16 #define sb scanf("%d",b[i]); 17 #define qq printf("*****\n"); 18 int n,m,tt; 19 const int MAXN = 110; 20 const int MAXM=10000;//最大边数 21 int F[MAXN];//并查集使用 22 struct Edge 23 { 24 int u,v,w; 25 }edge[MAXN*MAXN];//存储边的信息,包括起点/终点/权值 26 Edge anss[MAXN*MAXN]; 27 int tol;//边数,加边前赋值为0 28 void addedge(int u,int v,int w) 29 { 30 edge[tol].u=u; 31 edge[tol].v=v; 32 edge[tol++].w=w; 33 } 34 bool cmp(Edge a,Edge b) 35 {//排序函数,讲边按照权值从小到大排序 36 if(a.w!=b.w)return a.w<b.w; 37 else if(a.u!=b.u)return a.u<b.u; 38 else return a.v<b.v; 39 } 40 int find(int x) 41 { 42 if(F[x]==-1)return x; 43 else return F[x]=find(F[x]); 44 } 45 int cnt=0;//计算加入的边数 46 int Kruskal(int n)//传入点数,返回最小生成树的权值,如果不连通返回-1 47 { 48 memset(F,-1,sizeof(F)); 49 sort(edge,edge+tol,cmp); 50 int ans=0; 51 for(int i=0;i<tol;i++) 52 { 53 int u=edge[i].u; 54 int v=edge[i].v; 55 int w=edge[i].w; 56 int t1=find(u); 57 int t2=find(v); 58 if(t1!=t2) 59 { 60 ans+=w; 61 anss[cnt]=edge[i]; 62 F[t1]=t2; 63 cnt++; 64 } 65 if(cnt==n-1)break; 66 } 67 if(cnt<n-1)return -1;//不连通 68 else return ans; 69 } 70 bool cmp2(Edge a,Edge b) 71 { 72 if(a.u!=b.u)return a.u<b.u; 73 else return a.v<b.v; 74 } 75 int main() 76 { 77 #ifndef ONLINE_JUDGE 78 freopen("1.in","r",stdin); 79 #endif 80 int T; 81 scanf("%d",&T); 82 while(T--) 83 { 84 scanf("%d",&n); 85 tol=0; 86 cnt=0; 87 int w; 88 for(int i=1;i<=n;i++) 89 for(int j=1;j<=n;j++) 90 { 91 scanf("%d",&w); 92 if(j<=i)continue; 93 if(w==0)continue; 94 addedge(i,j,w); 95 } 96 int ff=Kruskal(n); 97 if(ff==-1) 98 { 99 printf("-1\n"); 100 continue; 101 } 102 else 103 { 104 sort(anss,anss+cnt,cmp2); 105 for(int i=0;i<cnt-1;i++) 106 printf("%d %d ",anss[i].u,anss[i].v); 107 printf("%d %d\n",anss[cnt-1].u,anss[cnt-1].v); 108 } 109 } 110 return 0; 111 }