ZOJ 3204 Connect them(字典序输出)

 

主要就是将最小生成树的边按字典序输出。

读取数据时,把较小的端点赋给u,较大的端点号赋值给v。 这里要用两次排序,写两个比较器: 第一次是将所有边从小到大排序,边权相同时按u从小到大,u相同时按v从小到大,用kruskal求出最小生成树。 第二次将求出的最小生成树的边在排序,这次只要按u、v从小到大排序即可。

#include <algorithm>
#include <cstring>
#include <cstdio>

using namespace std;

int index1;
int n,cost,idx,t;
int ans;

struct Edge{
    int u,v;
    int cost;

}edge[5500],MST[110];

struct UF{
    int father[110];

    void unit(){
        for(int i=1;i<=n;i++){
            father[i]=i;
        }
    }

    int find_root(int x){
        if(father[x]!=x)
            father[x]=find_root(father[x]);
        return father[x];
    }

    void Union(int fa,int fb){
        father[fb]=fa;
    }
}uf;

bool cmp1(const Edge t1,const Edge t2){
    if(t1.cost!=t2.cost)
        return t1.cost<t2.cost;
    if(t1.u!=t2.u)
        return t1.u<t2.u;
    else
        return t1.v<t2.v;
}

bool cmp2(const Edge t1,const Edge t2){
   if(t1.u!=t2.u)
        return t1.u<t2.u;
   else
        return t1.v<t2.v;
}

int main()
{
    scanf("%d",&t);
    for(int q=0;q<t;q++){
        scanf("%d",&n);
        index1=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=i;j++)
                scanf("%d",&cost);
            for(int j=i+1;j<=n;j++){
                scanf("%d",&cost);
                if(cost!=0){
                    edge[index1].u=i;
                    edge[index1].v=j;
                    edge[index1].cost=cost;
                    index1++;
                }
            }
        }
        
        sort(edge,edge+index1,cmp1);
        uf.unit();
        int count=0;
        idx=0;
        
        for(int i=0;i<index1;i++){
            int u=edge[i].u;
            int v=edge[i].v;
            int fu=uf.find_root(u);
            int fv=uf.find_root(v);
            if(count==n-1){
                break;
            }
            if(fu!=fv){
                MST[idx].u=u;
                MST[idx].v=v;
                MST[idx].cost=cost;
                idx++;
                count++;
                uf.Union(fu,fv);
            }
        }
        if(count<n-1){
            printf("-1\n");
        }
        else{
            sort(MST,MST+idx,cmp2);
            for(int i=0;i<idx;i++){
                //果真要按照下面的输入,否则为presentation error 。。。
                if(i==0)
                    printf("%d %d",MST[i].u,MST[i].v);
                else
                    printf(" %d %d",MST[i].u,MST[i].v);
            }
            printf("\n");
        }
    }
    return 0;
}

 

 

 

posted @ 2013-08-24 19:43  辰曦~文若  阅读(258)  评论(0编辑  收藏  举报