zoukankan      html  css  js  c++  java
  • 最小生成树唯一性判断-UESTC1959天才钱vs学霸周

    天才钱vs学霸周

    Time Limit: 1000 MS     Memory Limit: 256 MB
    Submit Status

    有一天,天才钱学霸周闲的无聊玩起了游戏,游戏内容是这样的,现在有nn个城堡 mm个不同的桥,每一个桥连接着两个不同的城堡,并且已知这mm个桥可以使nn个城堡连通,此外每一个桥都有重量vv。两位大爷需要给出选择桥的方案使得所有城堡被连通,注意两位大爷的方案不能完全相同(至少存在一个桥不相同),已知周大爷优先给出方案(因此钱大爷的方案必须不同于周大爷)。规则很诡异,如果钱大爷的方案中桥的重量之和周大爷的方案中桥的重量之和,那么钱大爷获胜,反之周大爷获胜。两位大爷都很聪明,他们会给出最优方案。现在你需要计算谁会赢。

    Input

    第一行输入两个值nn2n20002≤n≤2000),mm (nm200000n≤m≤200000) 接下来mm行,每一行输入三个值aa (1an1≤a≤n),bb(1bn1≤b≤n),vv(1v10181≤v≤1018),其中a!=ba!=b

    Output

    如果钱大爷获胜输出“zin”,反之输出“ogisosetsuna” 。

    Sample input and output

    Sample InputSample Output
    2 2
    1 2 1
    1 2 1
    zin

    Hint

    样例和test1不同

    Source

    2018 UESTC ACM Training for Graph Theory            
    题解:其实就是最小生成树唯一性的判定Orz......;












     利用并查集,按边权从小到大排序,然后对于每一个权值对应的边,先查找边的两个点不在同一集合的数量cnt1,然后再边枚举每一条不在同一集合的,并将边的两点合并到同一集合,计算数量cnt2,,对于每一权值,如果有cnt1>cnt2这说明最小生成树不唯一。

    AC代码为:

    #include<map>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    typedef long long LL;
    const int N=2000+10;
    const int M=200000+10;
    int fa[N];
    map<LL,int> mm;
    vector<int> E[M];
    
    struct node{
        int u,v;
        LL w;
    }edge[M];
    
    bool cmp(node a,node b)
    {
        return a.w<b.w;
    }
    
    void init()
    {
        for(int i=0;i<N;i++) fa[i]=i;
    }
    
    int fi(int x)
    {
        return x==fa[x]?x:fa[x]=fi(fa[x]);
    }
    
    void Union(int x,int y)
    {
        int fx=fi(x),fy=fi(y);
        if(fx!=fy) fa[fx]=fy;
    }
    
    int main()
    {
        init();
        int n,m,cnt=1;
        int cnt1=0,cnt2=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++) scanf("%d%d%lld",&edge[i].u,&edge[i].v,&edge[i].w);
        sort(edge+1,edge+1+m,cmp);
        for(int i=1;i<=m;i++){
            if(!mm[edge[i].w]) mm[edge[i].w]=cnt,cnt++;
            int pos=mm[edge[i].w];
            E[pos].push_back(i);
        }
        for(int i=1;i<cnt;i++)
    	{
            for(int j=0;j<E[i].size();j++)
    		{
                int pos=E[i][j];
                if(fi(edge[pos].u)!=fi(edge[pos].v)) cnt1++;
            }
            for(int j=0;j<E[i].size();j++)
    		{
                int pos=E[i][j];
                if(fi(edge[pos].u)!=fi(edge[pos].v))
    			{
                    Union(edge[pos].u,edge[pos].v);
                    cnt2++;
                }
            }
            if(cnt1>cnt2) break;
        }
        if(cnt1>cnt2) printf("zin
    ");
        else printf("ogisosetsuna
    ");
        return 0;
    }

  • 相关阅读:
    query and join operation after sharding
    Windows Phone中的几种集合控件
    什么是SOPA SOPA的危害
    自动刷新人人网API session_key方法
    Windows Phone XNA创建简单局域网游戏
    static 修饰MySqlConnection引发的异常
    $Dsu$ $on$ $Tree$ 复习
    $Noip$前的小总结哦
    $NOIP2018$ 暴踩全场计划实施方案
    $NOIP2018$ 爆踩全场记
  • 原文地址:https://www.cnblogs.com/csushl/p/9386530.html
Copyright © 2011-2022 走看看