zoukankan      html  css  js  c++  java
  • 2017乌鲁木齐区域赛I(带权并查集)

    #include<bits/stdc++.h>
    using namespace std;
    int f[200010];//代表元
    long long rl[200010];//记rl[i]为结点i到根的路径上所有边的亦或和(这里可以忽视 x(0)的情况)
    void init(int n)
    {
        for(int i=1;i<=n;i++)
            f[i]=i,rl[i]=0;//初始化
    }
    int fd(int x)//并查集模板
    {
        if(f[x]==x)
            return x;
        int fa=f[x];
        f[x]=fd(f[x]);
        rl[x]=rl[x]^rl[fa];//由于x更换了代表元,换的路径要算上
        return f[x];
    }
    int join(int x,int y,long long val)
    {
        int fx=fd(x),fy=fd(y);
        if(fx==fy)
            return 0;
        f[fx]=fy;
        rl[fx]=rl[fx]^rl[x]^rl[y]^val;//同一个集合(代表元为 c)
    //内两个元素 a 和 b 的亦或值为 x(a) xor x(b) = (x(a) xor x(c)) xor (x(b) xor x(c))。
        return 1;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n,c;
            scanf("%d%d",&n,&c);
            int x,y;
            for(int i=1;i<n;i++)
                scanf("%d%d",&x,&y);
            init(n);
            int xx,yy;
            long long val;
            int ans=c;
            for(int i=1;i<=c;i++)
            {
                scanf("%d%d%lld",&xx,&yy,&val);
                if(ans!=c)
                    continue;
                if(!join(xx,yy,val)&&(rl[xx]^rl[yy])!=val)//当某一条信息中两点xx与yy在同一连通块上,
                //那么就必须满足xx与yy各自代表元异或的值等于val,否则就停止,只能满足之前的要求数量。
                    ans=i-1;
            }
            printf("%d ",ans);
        }
        return 0;
    }
    //带权并查集可以考虑模板,根据实际问题修改里面的变量

    保持热爱 不懈努力 不试试看怎么知道会失败呢(划掉) 世上无难事 只要肯放弃(划掉)
  • 相关阅读:
    ado 查询文件数据库
    S60平台简体汉字处理浅谈转symbian wiki
    symbian在收件箱创建短信(转)
    symbian得到收件箱中未读短信的数目
    enable marquee with the animated in the ListBox
    如何为Series60绘制一个常驻顶端的提示图标 [symbian]
    Symbian 得到左右软键项(CBA)的内容
    asp.net 中如何请求一个其它网站的页面
    使S60程序全屏运行,fullscreen
    symbian程序在后台运行
  • 原文地址:https://www.cnblogs.com/ldudxy/p/9519979.html
Copyright © 2011-2022 走看看