poj 1733 Parity game(带权并查集)

来源:互联网 发布:老巴黎西洋家具淘宝网 编辑:程序博客网 时间:2024/04/30 01:43

题目大意是:一个由0,1组成的数字串~~,现在你问一个人,第i位到第j位的1的个数为奇数还是偶数。一共会告诉你几组这样的数

要你判断前k组这个人回答的都是正确的,到第k+1组,这个人说的是错的,要你输出这个k,要是这个人回答的都是正确的,则输出组数

思路:这题一看就想到要用并查集做了,不过一看数据这么大,感觉有点棘手,其实,我们仔细一想可以发现,我们需要记录的是出现过的节点到根节点的1个奇偶性,这与区间端点的大小并没有关系,于是想到我们可以用map映射即可(或者离散化),这样就解决了大数据了。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<map>using namespace std;#define MAXN 5050int parent[MAXN];int kind[MAXN];int n,m,Index;void Initiate(){    for(int i=0;i<MAXN;i++){        parent[i]=i;    }    memset(kind,0,sizeof(kind));}int Find(int x){    if(x==parent[x]){        return parent[x];    }    int tmp=Find(parent[x]);    kind[x]=(kind[x]+kind[parent[x]])%2;    return parent[x]=tmp;}bool Union(int u,int v,int d){    int r1=Find(u),r2=Find(v);    if(r1==r2){        if(kind[u]!=(kind[v]+d)%2)return false;        return true;    }    parent[r1]=r2;    kind[r1]=(kind[v]-kind[u]+d+2)%2;    return true;}int main(){    int a,b,d,pos;    char str[11];    while(~scanf("%d%d",&n,&m)){        Index=0;        map<int,int>mp;        bool flag=true;        Initiate();        for(int i=0;i<m;i++){            scanf("%d%d%s",&a,&b,str);            d=(str[0]=='e'?0:1);a--;            if(mp.find(a)==mp.end()){                mp[a]=Index++;            }            if(mp.find(b)==mp.end()){                mp[b]=Index++;            }            if(!flag)continue;            if(!Union(mp[a],mp[b],d)){                flag=false;                pos=i;            }        }        if(flag)pos=m;        printf("%d\n",pos);    }    return 0;}


0 0
原创粉丝点击