zoukankan      html  css  js  c++  java
  • 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
    ");
            }
            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("
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    JS站点
    1011 World Cup Betting (20分)
    1007 Maximum Subsequence Sum (25分)(动态规划DP)
    1006 Sign In and Sign Out (25分)
    1005 Spell It Right (20分)
    1004 Counting Leaves (30分)(DFS)
    1003 Emergency (25分)(Dijkstra算法)
    1002 A+B for Polynomials (25分)
    1001 A+B Format (20分)
    canvas
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/3279700.html
Copyright © 2011-2022 走看看