POJ - 1733 Parity game 带权并查集+离散化

题目大意:有10E位数,每位上的数不是1就是0。现在给出第n位到第m位的1的数量的奇偶性,判断所给出的话有几句是对的

解题思路:有10E位数,肯定要离散化处理

因为有可能给出的区间是左端点等于右端点的,所以每次都把左端点的值减去1再进行处理

给出了区间的奇偶性,就要找一下是否和前面的矛盾,如果该区间的左端点的根节点和右端点的根节点是相同的,那么就可以判断是否正确了

如果根节点不同,就进行合并,合并时要注意判断是谁的根节点比较大

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
using namespace std;
#define maxn 10010
int p[maxn], r[maxn], u[maxn], v[maxn], q[maxn], ans, n, M;
map<int,int> m;

int find(int x) {
    if(x == p[x])
        return x;
    int t = find(p[x]);
    r[x] = (r[x] + r[p[x]]) % 2;
    return p[x] = t;
}

void init() {
    scanf("%d", &M);
    char str[100];
    for(int i = 0; i < M; i++) {
        scanf("%d%d%s", &u[i], &v[i], str);
        if(strcmp(str, "even") == 0)
            q[i] = 0;
        else
            q[i] = 1;
    }
    m.clear();
    int cnt = 1;
    for(int i = 0; i < M; i++) {
        if(!m[u[i] - 1])
            m[u[i] - 1] = cnt++;
        if(!m[v[i]])
            m[v[i]] = cnt++;
    }

    for(int i = 0; i < M; i++) {
        p[m[u[i] - 1]] = m[u[i] - 1];
        p[m[v[i]]] = m[v[i]];
        r[m[u[i] - 1]] = r[m[v[i]]] = 0;
    }
}

void solve() {
    ans = -1;
    for(int i = 0; i < M; i++) {
        int x = m[u[i] - 1];
        int y = m[v[i]];
        int xx = find(m[u[i] - 1]);
        int yy = find(m[v[i]]);

        if(xx == yy) {
            if((r[x] - r[y] + 2) % 2 != q[i]) {
                ans = i;
                return ;
            }
        }
        else if(xx < yy){
            p[xx] = yy;
            r[xx] = (r[y] + q[i] - r[x] + 2) % 2;
        }
        else {
            p[yy] = xx;
            r[yy] = (r[x] - r[y] - q[i] + 4) % 2;
        }
    }
}

int main() {
    while(scanf("%d", &n) == 1) {
        init();
        solve();
        if(ans == -1)
            printf("%d\n", M);
        else
            printf("%d\n", ans);
    }
    return 0;
}
时间: 2024-08-25 01:53:15

POJ - 1733 Parity game 带权并查集+离散化的相关文章

POJ 1773 Parity game 带权并查集

分析:带权并查集,就是维护一堆关系 然后就是带权并查集的三步 1:首先确定权值数组,sum[i]代表父节点到子节点之间的1的个数(当然路径压缩后代表到根节点的个数) 1代表是奇数个,0代表偶数个 2:设计路径压缩算法 sum[x]=(sum[x]+sum[t])%2; 3:弄清合并根节点时的操作,小的在上: 注:这个题需要离散化 #include <stdio.h> #include <string.h> #include <algorithm> using names

poj 1733 Parity game 【种类并查集+离散化】

Parity game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6767   Accepted: 2616 Description Now and then you play the following game with your friend. Your friend writes down a sequence consisting of zeroes and ones. You choose a conti

poj 2912 Rochambeau(带权并查集 + 暴力)

题目:poj 2912 Rochambeau(带权并查集 + 暴力) 题目大意:题目给出三个团队和一个裁判,这三个团队和裁判一起玩剪刀石头布,然后规定每个团队必须出一样的,只有裁判可以任意出.然后给出关系,x > y 代表 x 赢y , x < y代表 y 赢 x , 相等则出的一样.问这样的关系可以推出裁判是哪个吗?可以需要说明从第一条到第几条推出来的,不可以也要说明是不可能出现这样的关系,还是裁判不唯一. 解题思路:这题重点是裁判在里面会扰乱关系,并且n * m 才 100000,完全可以

POJ 1988 Cube Stacking (带权并查集)

题目链接:http://poj.org/problem?id=1988 有n个元素,开始每个元素自己 一栈,有两种操作,将含有元素x的栈放在含有y的栈的顶端,合并为一个栈.第二种操作是询问含有x元素下面有多少个元素. 经典的带权并查集,cnt表示包含这个元素的集合中所有元素个数,dis表示这个元素离最上面元素的个数(距离). 看代码领会一下吧. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio>

POJ 1182 食物链(带权并查集)

http://poj.org/problem?id=1182 题意: 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同类. 第二种说法是"2 X Y",表示X吃Y. 此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话

BZOJ 3362 POJ 1984 Navigation Nightmare 带权并查集

题目大意:一些农场由一些东西向或者南北向的路相互连接.在不断加边的过程中会询问两个农场的曼哈顿距离是多少,如果目前还不连通,那么输出-1. 思路:带权并查集,f[i]为点i到father[i]的距离,要维护两个值,一个是东西向的距离,一个是南北向的距离,因为以后更新的时候要用到.在合并的时候有些特殊.现在有一条边(x->y),设fx为x的根,fy为y的根,那么现在知道f到fx的距离,y到fy的距离,还知道x到y的距离,设fx到fy的距离为dis,则dis + f[y] = f[x] + edge

POJ 1182 食物链 (带权并查集)

动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种.有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同类. 第二种说法是"2 X Y",表示X吃Y. 此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的.当一句话满足下列三条之一时,这句话就是假话,否则

POJ 1984 - Navigation Nightmare - [带权并查集]

题目链接:http://poj.org/problem?id=1984 Time Limit: 2000MS Memory Limit: 30000K Case Time Limit: 1000MS Description Farmer John's pastoral neighborhood has N farms (2 <= N <= 40,000), usually numbered/labeled 1..N. A series of M (1 <= M < 40,000)

Parity game——带权并查集

题目链接 题意: 你一个字符串,由0和1组成,并且告诉你子串里面1的个数,假设前面的话都是对的,问你到哪一句和前面的话矛盾. 题解: 首先,发现n很大,但是问题数m不多,所以先离散化 d数组表示序列S的前缀和d[l~r]有偶数个1,等价于d[l-1]与d[r]奇偶性相同. d[l~r]有奇数个1,等价于d[l-1]与d[r]奇偶性不同. 然后通过异或满足上面传递关系 即 奇偶性相同异或为偶  奇偶性不同异或为奇 集合合并方法与 How Many Answers Are Wrong 类似 d[i]