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 namespace std;
const int N=5e3+5;
struct Node{
  int l,r,v;
}p[N];
int a[N<<1],cnt;
char s[10];
int fa[N<<1],sum[N<<1];
int find(int x){
   if(x==fa[x])return x;
   int t=fa[x];
   fa[x]=find(fa[x]);
   sum[x]=(sum[x]+sum[t])%2;
   return fa[x];
}
int main()
{
    int n;
    while(~scanf("%d%d",&n,&n)){
    cnt=0;
    for(int i=1;i<=n;++i){
      scanf("%d%d%s",&p[i].l,&p[i].r,s);
      if(s[0]==‘e‘)p[i].v=0;
      else p[i].v=1;
      --p[i].l;
      a[++cnt]=p[i].l,a[++cnt]=p[i].r;
    }
    sort(a+1,a+1+cnt);
    cnt=unique(a+1,a+1+cnt)-a-1;
    for(int i=0;i<=cnt;++i)fa[i]=i,sum[i]=0;
    int ans=0;
    for(int i=1;i<=n;++i){
       p[i].l=lower_bound(a+1,a+1+cnt,p[i].l)-a;
       p[i].r=lower_bound(a+1,a+1+cnt,p[i].r)-a;
       int u=find(p[i].l),v=find(p[i].r);
       if(u==v){
          if((2-sum[p[i].r]-sum[p[i].l])%2!=p[i].v)break;
       }
       else if(u<v){
          fa[v]=u;
          sum[v]=sum[p[i].r]-sum[p[i].l]-p[i].v;
       }
       else{
          fa[u]=v;
          sum[u]=sum[p[i].l]-sum[p[i].r]+p[i].v;
       }
       ++ans;
    }
    printf("%d\n",ans);
    }
    return 0;
}

时间: 2024-10-12 19:19:46

POJ 1773 Parity game 带权并查集的相关文章

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

题目大意:有10E位数,每位上的数不是1就是0.现在给出第n位到第m位的1的数量的奇偶性,判断所给出的话有几句是对的 解题思路:有10E位数,肯定要离散化处理 因为有可能给出的区间是左端点等于右端点的,所以每次都把左端点的值减去1再进行处理 给出了区间的奇偶性,就要找一下是否和前面的矛盾,如果该区间的左端点的根节点和右端点的根节点是相同的,那么就可以判断是否正确了 如果根节点不同,就进行合并,合并时要注意判断是谁的根节点比较大 #include<cstdio> #include<algo

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]

POJ 1984 Navigation Nightmare 二维带权并查集

题目来源:POJ 1984 Navigation Nightmare 题意:给你一颗树 k次询问 求2点之间的曼哈顿距离 并且要在只有开始k条边的情况下 思路:按照方向 我是以左上角为根 左上角为原点 dx[i]为i点距离根的x坐标 dy[]是y坐标 这两个可以通过路径压缩求出 只不过是二维而已 #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; const int m