hdu3234 Exclusive-OR 带权并查集

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu3234 Exclusive-OR 带权并查集相关的知识,希望对你有一定的参考价值。

不想再调这道题了。。。这题我早就会了,但是读入实在是坑。。。。就是坑。。。。没错,这次真的是坑。。。。。。

不能在坑题上浪费太多时间,既没有明显提高代码能力,又不能提高思维,也不能学到知识点。

我只能说,出题人心理为何如此阴暗,出这样的题和报复社会有什么区别。。。

技术分享
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;

int n,m;
char op[10];int p,q,v;
int k,pk[40];
vector<int> d[40];int dn;
int fa[maxn],w[maxn],val[maxn];
int flag;
int rk;
int sz[maxn];

void Init()
{
    REP(i,0,2) fa[i]=i,w[i]=0,val[i]=-1,sz[i]=1;
    REP(i,0,20) d[i].clear();
}

int find(int x)
{
    if(fa[x]==x) return x;
    int t=find(fa[x]);
    w[t]=0;
    w[x]^=w[fa[x]];
    return fa[x]=t;
}

void Union(int p,int q,int v)
{
    if(flag==0) return;
    int x=find(p),y=find(q);
    if(x==y){
        if((w[p]^w[q])!=v) flag=0;
    }
    else{
        if(sz[x]>sz[y]) swap(x,y),swap(p,q);
        if(~val[x]&&~val[y]){
            if((w[p]^val[x]^w[q]^val[y])!=v) flag=0;
            else{
                fa[x]=y;
                sz[y]+=sz[x];
                sz[x]=0;
                w[x]=(w[p]^w[q]^v);
                w[y]=0;
            }
        }
        else{
            fa[x]=y;
            w[x]=(w[p]^w[q]^v);
            w[y]=0;
            if(val[y]==-1){
                if(~val[x]) val[y]=(val[x]^w[x]);
            }
        }
    }
    if(flag==0) printf("The first %d facts are conflicting.\n",rk);
}

void change(int p,int v)
{
    if(flag==0) return;
    int x=find(p);
    if(~val[x]){
        if((w[p]^val[x])!=v) flag=0;
    }
    else val[x]=(v^w[p]);
    if(flag==0) printf("The first %d facts are conflicting.\n",rk);
}

bool cmp(int a,int b)
{
    return fa[a]<fa[b];
}

int query()
{
    REP(i,1,k) d[i].clear();
    int res=0;
    sort(pk+1,pk+k+1,cmp);
    dn=1;
    d[1].push_back(pk[1]);
    int px=fa[pk[1]];
    REP(i,2,k){
        if(fa[pk[i]]==px) d[dn].push_back(pk[i]);
        else{
            ++dn;
            px=fa[pk[i]];
            d[dn].push_back(pk[i]);
        }
    }
    REP(i,1,dn){
        if((int)d[i].size()%2==0){
            for(int j=0;j<d[i].size();j++) res^=w[d[i][j]];
        }
        else{
            int x=fa[d[i][0]];
            if(val[x]==-1) return -1;
            for(int j=0;j<d[i].size();j++) res^=(val[x]^w[d[i][j]]);
        }
    }
    return res;
}

void solve()
{
    flag=1;rk=0;
    REP(i,1,m){
        scanf("%s",op);
        if(op[0]==I){
            ++rk;
            gets(op);
            if(sscanf(op,"%d%d%d",&p,&q,&v)==3) Union(p,q,v);
            else change(p,q);
        }
        else{
            scanf("%d",&k);
            REP(i,1,k){
                scanf("%d",&pk[i]);
                find(pk[i]);
            }
            if(flag==0) continue;
            ll tmp=query();
            if(tmp==-1) printf("I don‘t know.\n");
            else printf("%d\n",tmp);
        }
    }
}

int main()
{
    freopen("in.txt","r",stdin);
    int casen=1;
    while(~scanf("%d%d",&n,&m)){
        if(n==0&&m==0) break;
        printf("Case %d:\n",casen++);
        Init();
        solve();
        puts("");
    }
    return 0;
}

/**
6 5
I 1 2 1
I 3 4 2
I 4 5 3
Q 2 3 5
Q 4 1 2 3 5
2 6
I 0 1 3
Q 1 0
Q 2 1 0
I 0 2
Q 1 1
Q 1 0
3 3
I 0 1 6
I 0 2 2
Q 2 1 2
2 4
I 0 1 7
Q 2 0 1
I 0 1 8
Q 2 0 1
0 0
*/
View Code

 

以上是关于hdu3234 Exclusive-OR 带权并查集的主要内容,如果未能解决你的问题,请参考以下文章

HDU 3047 Zjnu Stadium 带权并查集

HDU1289 A Bug's Life (带权并查集)

Travel(HDU 5441 2015长春区域赛 带权并查集)

带权并查集复习-HDU3038

hdu2818(带权并查集)

HDU3635 Dragon Balls(带权并查集)