poj1733 Parity game[带权并查集or扩展域]

地址


连通性判定问题。(具体参考lyd并查集专题该题的转化方法,反正我菜我没想出来)。转化后就是一个经典的并查集问题了。

带权:要求两点奇偶性不同,即连边权为1,否则为0,压缩路径时不断异或,可以通过0或1得到两点的关系。合并时解一个位运算的方程,可得一个根连向另一个根的权值,看code,就不细讲了。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<queue>
 7 #define dbg(x) cerr<<#x<<" = "<<x<<endl
 8 #define ddbg(x,y) cerr<<#x<<" = "<<x<<"   "<<#y<<" = "<<y<<endl
 9 using namespace std;
10 typedef long long ll;
11 template<typename T>inline char MIN(T&A,T B){return A>B?A=B,1:0;}
12 template<typename T>inline char MAX(T&A,T B){return A<B?A=B,1:0;}
13 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
14 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
15 template<typename T>inline T read(T&x){
16     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
17     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
18 }
19 const int N=10000+7;
20 struct kishin_sagume{
21     int l,r,p;
22 }q[N];
23 int a[N<<1],fa[N<<1],d[N<<1];
24 int L,n,m,x,y,fx,fy,flag,i;
25 inline int Get(int x){
26     if(fa[x]==x)return x;
27     int ret=Get(fa[x]);d[x]^=d[fa[x]];
28     return fa[x]=ret;
29 }
30 
31 int main(){//freopen("test.in","r",stdin);//freopen("test.out","w",stdout);
32     read(L),read(n);char s[8];
33     for(i=1;i<=n;++i){
34         read(q[i].l),read(q[i].r),a[++m]=--q[i].l,a[++m]=q[i].r;
35         scanf("%s",s);q[i].p=s[0]=='o';
36     }
37     sort(a+1,a+m+1),m=unique(a+1,a+m+1)-a-1;
38     for(i=1;i<=m;++i)fa[i]=i;
39     for(i=1;i<=n;++i){
40         x=lower_bound(a+1,a+m+1,q[i].l)-a,y=lower_bound(a+1,a+m+1,q[i].r)-a;
41         fx=Get(x),fy=Get(y);
42         if(fx^fy)fa[fx]=fy,d[fx]=q[i].p^d[x]^d[y];
43         else if(d[x]^d[y]^q[i].p)break;
44     }
45     return printf("%d\n",i-1),0;
46 }

扩展域:同奇偶时连奇数域和偶数域分别连边,否则交错,边的含义是可以产生关系,或者说可以推出。已知他是满足传递性的。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<queue>
 7 #define dbg(x) cerr<<#x<<" = "<<x<<endl
 8 #define ddbg(x,y) cerr<<#x<<" = "<<x<<"   "<<#y<<" = "<<y<<endl
 9 using namespace std;
10 typedef long long ll;
11 template<typename T>inline char MIN(T&A,T B){return A>B?A=B,1:0;}
12 template<typename T>inline char MAX(T&A,T B){return A<B?A=B,1:0;}
13 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
14 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
15 template<typename T>inline T read(T&x){
16     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
17     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
18 }
19 const int N=10000+7;
20 struct matara_okina{
21     int l,r,p;
22 }q[N];
23 int a[N<<1],fa[N<<2];
24 int L,n,m,x,y,i;
25 inline int Get(int x){
26     return fa[x]^x?fa[x]=Get(fa[x]):x;
27 }
28 
29 int main(){//freopen("test.in","r",stdin);//freopen("test.out","w",stdout);
30     read(L),read(n);char s[8];
31     for(i=1;i<=n;++i){
32         read(q[i].l),read(q[i].r),a[++m]=--q[i].l,a[++m]=q[i].r;
33         scanf("%s",s);q[i].p=s[0]=='o';
34     }
35     sort(a+1,a+m+1),m=unique(a+1,a+m+1)-a-1;
36     for(i=1;i<=(m<<1);++i)fa[i]=i;
37     for(i=1;i<=n;++i){
38         x=lower_bound(a+1,a+m+1,q[i].l)-a,y=lower_bound(a+1,a+m+1,q[i].r)-a;
39         if(q[i].p){
40             if(Get(x)==Get(y))break;
41             fa[Get(x)]=Get(y+m),fa[Get(x+m)]=Get(y);
42         }
43         else{
44             if(Get(x)==Get(y+m))break;
45             fa[Get(x)]=Get(y),fa[Get(x+m)]=Get(y+m);
46         }
47     }
48     return printf("%d\n",i-1),0;
49 }

 

转载于:https://www.cnblogs.com/saigyouji-yuyuko/p/10634415.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值