POJ 1733 Parity game(加权并查集)

题意:这是一个01的串,然后有m个类似于询问的东西,每次询问都告诉你这个区间的和为奇数还是偶数,让你判断正确的有几句,如果不正确,直接跳出

思路:和华中科技大学的决赛差不多,我们将奇数设为1,偶数为0,那我们可以发现他们的奇偶性可以用异或代替,然后就穿一样了,加上判断条件就OK了,记得离散化

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long LL;
inline LL read()
{
    LL x=0,f=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

const int maxn=2e4+7;

struct node
{
    int x,y,w;
}q[maxn];
int fa[maxn];
int sum[maxn];
int sa[maxn];
int len;
int Find(int x)
{
    if(x!=fa[x]){
        int t=fa[x];
        fa[x]=Find(fa[x]);
        sum[x]^=sum[t];
    }
    return fa[x];
}

int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m)){

        len=0;
        int ans=0;
        bool ok=false;
        char op[15];
        for(int i=1;i<=m;i++){
            int a,b,w;
            scanf("%d%d%s",&a,&b,op);
            if(op[0]=='e')w=0;
            else w=1;
            a--;
            q[i].x=a;q[i].y=b;q[i].w=w;
            sa[++len]=a;
            sa[++len]=b;
        }
        sort(sa+1,sa+1+len);
        len=unique(sa+1,sa+1+len)-sa-1;
        for(int i=0;i<=len;i++){
            fa[i]=i;
            sum[i]=0;
        }
        for(int i=1;i<=m;i++){
            int a=lower_bound(sa+1,sa+len+1,q[i].x)-sa;
            int b=lower_bound(sa+1,sa+len+1,q[i].y)-sa;
            int rta=Find(a);
            int rtb=Find(b);
            if(rta==rtb){
                if(sum[a]==sum[b]&&q[i].w==1)break;
                if(sum[a]!=sum[b]&&q[i].w==0)break;
                ans++;
            }
            else{
                fa[rta]=rtb;
                sum[rta]=sum[a]^sum[b]^q[i].w;
                ans++;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
/*
10 5
1 2 even
3 4 odd
5 6 even
1 6 even
7 10 odd
*/

 

posted @ 2018-10-31 19:21  啦啦啦天啦噜  阅读(184)  评论(0编辑  收藏  举报