Ural 1003 Parity(并查集)
来源:互联网 发布:java工程师学什么专业 编辑:程序博客网 时间:2024/06/05 20:38
题目地址:http://acm.timus.ru/problem.aspx?space=1&num=1003
二、
思路:
一、
1.区间和可表示为两前缀和相减:sum[R]-sum[L-1]。若区间[L,R]和为奇数,则连边(L-1)-->R,权值为1,否则权值为0。则由a->b和b->c可推出a->c的奇偶性。
2.使用并查集维护信息,设w[i]为i到其根结点的距离。则判断时只需判断(w[L-1]+w[R])%2是否满足条件。
3.由此,得出sum[fa[R]]-sum[fa[L-1])=(w[R]-w[L-1]+p+2)%2(+2防止负数)。
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define debugusing namespace std;const int maxn=10000+50;struct Node{ int l,r,id;};int a[maxn];Node q[maxn];int cnt1,cnt2,n,m;int fa[maxn],w[maxn];void init(){ cnt1=cnt2=0; memset(w,0,sizeof(w)); for(int i=0; i<=m*2; i++) fa[i]=i;}int Find(int x){ if(fa[x]==x) { return x; } else { int t=fa[x]; fa[x]=Find(fa[x]); w[x]=(w[x]+w[t])%2; return fa[x]; }}int main(){#ifdef debu freopen("in.txt","r",stdin);#endif // debug while(scanf("%d",&n)!=EOF) { if(n==-1) break; scanf("%d",&m); init(); for(int i=0; i<m; i++) { int l,r; char st[5]; scanf("%d%d%s",&l,&r,st); a[cnt1++]=l,a[cnt1++]=r; q[cnt2].l=l,q[cnt2].r=r; q[cnt2].id=(st[0]=='e')?0:1; cnt2++; } sort(a,a+cnt1); int cnt=unique(a,a+cnt1)-a; int ans=-1; for(int i=0; i<cnt2; i++) { int l=lower_bound(a,a+cnt,q[i].l)-a+1; int r=lower_bound(a,a+cnt,q[i].r)-a+1; if(q[i].l>n||q[i].r>n) { ans=i+1; break; } int x=Find(l-1),y=Find(r); if(x==y) { if(q[i].id!=(w[l-1]+w[r])%2) { ans=i+1; break; } } else { fa[x]=y; w[x]=(w[r]-w[l-1]+q[i].id+2)%2; } } if(ans==-1) printf("%d\n",m); else printf("%d\n",ans-1); } return 0;}
二、
1.对于每点,设置两集合一代表其本身,另一代表其对立集合。
2.当一区间和为偶数时,fa[L-1]与fa[R]同属一集合,fa[(L-1)']与fa[R']同属一集合。
2.当一区间和为奇数时,fa[(L-1)]与fa[R']同属一集合,fa[(L-1)']与fa[R]同属一集合。
3.判断是否处于对应的集合即可。
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define debugusing namespace std;const int maxn=20000+50;struct Node{ int l,r,id;};Node q[maxn];int n,m,cnt1,cnt2;int fa[maxn],a[maxn];void init(){ cnt1=cnt2=0; for(int i=0; i<=4*m+2; i++) fa[i]=i;}int Find(int x){ return fa[x]==x?x:fa[x]=Find(fa[x]);}int main(){#ifdef debu freopen("in.txt","r",stdin);#endif // debug while(scanf("%d",&n)!=EOF) { if(n==-1) break; scanf("%d",&m); init(); for(int i=0; i<m; i++) { int l,r; char st[5]; scanf("%d%d%s",&l,&r,st); a[cnt1++]=l,a[cnt1++]=r; q[cnt2].l=l,q[cnt2].r=r; q[cnt2].id=(st[0]=='e')?0:1,cnt2++; } sort(a,a+cnt1); int cnt=unique(a,a+cnt1)-a; int ans=-1; for(int i=0; i<m; i++) { int l=lower_bound(a,a+cnt,q[i].l)-a+1; int r=lower_bound(a,a+cnt,q[i].r)-a+1; if(q[i].l>n||q[i].r>n) { ans=i+1; break; } int x=Find(l-1),xx=Find(2*m+1+l-1); int y=Find(r),yy=Find(2*m+1+r); if(q[i].id==0) { if(x==yy||y==xx) { ans=i+1; break; } else { fa[x]=y; fa[xx]=yy; } } else { if(x==y||xx==yy) { ans=i+1; break; } else { fa[x]=yy; fa[xx]=y; } } } if(ans==-1) printf("%d\n",m); else printf("%d\n",ans-1); } return 0;}
阅读全文
0 0
- Ural 1003 Parity(并查集)
- ural 1003 Parity 并查集
- URAL 1003 Parity(并查集)
- poj1733 & Ural 1003 Parity Game (hash+并查集 )
- ural 1003. Parity(并查集)
- 【并查集】Parity
- POJ1733 parity game(并查集)
- Parity game 并查集
- Parity game(代权并查集(区间))
- poj 1733 Parity game (并查集+向量偏移)
- POJ 1733 parity game (hash离散+并查集)
- POJ - 1733 Parity game (带权并查集)
- Poj 1733 Parity Game(离散化+并查集)
- poj 1733 Parity game(种类并查集)
- CEOI 1999 Parity game (并查集+离散化)
- poj 1733 Parity game(带权并查集)
- 并查集——奇偶性(Parity)
- poj-1703(并查集) Parity game
- jsp简介
- 间接寻址--简单操作
- Java Activiti(6)--流程变量的添加与获取(表act_ru_variable)
- Sicily 1798. Alice and Bob
- 模糊控制简介及数学基础 (模糊集合、隶属函数)
- Ural 1003 Parity(并查集)
- leetcode.array--42. Trapping Rain Water
- 算法设计与分析(屈婉玲)网络课学习笔记(一)
- JavaScript是如何实现继承的(六种方式)
- HDU-4476 Cut the rope (枚举、前缀和)
- 前端考试知识点归纳总结
- IntelliJ IDEA+SpringBoot中静态资源访问路径陷阱:静态资源访问404
- IP地址与Long型整数的相互转换
- HDU