ZOJ 3204 Connect them (kruskal+二级排序)

         难搞的是字典序,需要两次排序,我之前写的算法是正确的,就是排序的时候遗漏了一些东西导致最后出现错误。记住了。

 

        至于算法的证明,我至今还没有想的很明白,但是刚开始的时候直觉告诉我可以这样做,faint!~

 

#include<stdio.h> #include<string.h> #include<stdlib.h> int p[101]; int find(int x) {return x==p[x]?x:p[x]=find(p[x]);} struct edge { int from,to; int w; } a[5000],t,out[101]; int cmp1(const void *a,const void *b) { struct edge aa = *(struct edge*)a; struct edge bb = *(struct edge*)b; if( aa.w != bb.w ) return aa.w>bb.w; else if( aa.from != bb.from ) return aa.from-bb.from; else return aa.to-bb.to; } int cmp2(const void *a,const void *b) { struct edge aa = *(struct edge*)a; struct edge bb = *(struct edge*)b; if( aa.from != bb.from ) return aa.from>bb.from; else return aa.to>bb.to; } int main(void) { int cases,n,i,j; int w,count,from,to; int amount; scanf("%d",&cases); while( cases-- ) { scanf("%d",&n); count = 0; for( i = 1; i <= n; i++ )//initialize for( j = 1; j <= n; j++ ) { scanf("%d",&w); if( j <= i ) continue; if( w == 0 ) continue; t.from = i; t.to = j; t.w = w; a[++count] = t; } qsort(a+1,count,sizeof(a[0]),cmp1);//sort for( i = 1; i<=n;i++) p[i] = i; for( i=1,amount=0; i <= count;i++) //part of Kruskal { from = a[i].from; to = a[i].to; from = find(from); to = find(to); if( from == to) continue; p[from] = to; out[++amount] = a[i]; } if( amount == n-1 ) //if it is a MST,output { qsort(out+1,amount,sizeof(out[0]),cmp2); for( i=1;i<=amount;i++) printf(i==1?"%d %d":" %d %d",out[i].from,out[i].to); printf("/n"); } else printf("-1/n"); } return 0; }

 

 

你可能感兴趣的:(ZOJ 3204 Connect them (kruskal+二级排序))