UVALive - 4487 Exclusive-OR 加权并查集

来源:互联网 发布:诸暨市淘宝司法拍卖 编辑:程序博客网 时间:2024/05/25 05:38

题目大意:有n个数,刚开始都不知道是什么,有三种操作,
I p v: 第p个数等于v
I p q v: 第p个数^第q个数的结果为v
Q k p1 p2 p3 .. pk: 要求回答第p1个数到第p2个数的异或的结果

解题思路:还是像以往一样压缩路径,只不过压缩的时候要并上权,参考别人的思路的….

http://www.cnblogs.com/kkrisen/archive/2014/07/01/3818269.html

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define maxn 21020int f[maxn], v[maxn], vis[maxn], a[maxn], T = maxn - 10;void init(int n) {    for(int i = 0; i <= n + 1; i++) {        f[i] = i;        v[i] = 0;        vis[i] = 0;     }    f[T] = T, v[T] = 0;}int find(int x) {    if(x != f[x]) {        int tmp = f[x];        f[x] = find(f[x]);        v[x] ^= v[tmp];     }    return f[x];}int uset(int p, int q, int val) {    int r1 = find(p);    int r2 = find(q);    if(r1 == r2) {        if((v[p] ^ v[q]) != val)            return 0;        else            return 1;       }    if(r1 == T)        swap(r1,r2);    f[r1] = r2;    v[r1] = v[p] ^ v[q] ^ val;    return 1;}int main() {    int n, Q, p, q, val, mark = 1;    char ch[2], str[40];    while(scanf("%d%d", &n, &Q) == 2 && n + Q) {        init(n);        printf("Case %d:\n", mark++);        bool err = 0;        int facts = 0;        for(int i = 1; i <= Q; i++) {            scanf("%s", ch);            if(ch[0] == 'I') {                facts++;                gets(str);                if(sscanf(str,"%d%d%d", &p, &q, &val) == 2) {                       val = q, q = T;                }                if(err)                    continue;                if(!uset(p,q,val)) {                    printf("The first %d facts are conflicting.\n", facts);                     err = 1;                }            }            else {                int k , ans = 0;                scanf("%d", &k);                for(int i = 1; i <= k; i++)  {                    scanf("%d", &a[i]);                    if(err)                        continue;                    int r = find(a[i]);                    ans ^= v[a[i]];                    a[i] = r;                    vis[r] ^= 1;                }                if(err)                    continue;                bool flag = 1;                for(int i = 1; i <= k; i++) {                    if(vis[a[i]]) {                        if(a[i] != T)                            flag = 0;                    }                       vis[a[i]] = 0;                  }                if(flag)                    printf("%d\n", ans);                else                    printf("I don't know.\n");            }           }        printf("\n");    }    return 0;}
0 0
原创粉丝点击