POJ1733 - Parity game - 并查集

这道题是带权并查集,只需要把权设成0或1就行,分别表示与根节点的关系。因为10亿个点,所以要用到离散化

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
int p[10005];
int dis[10005];
int ran[10005];
int tot;
struct num
{
	char oe[10];
	int st,ed;
	int id;
}po[5005];
int find(int n)
{
	int item;
	if(p[n]!=n)
	{
		item=p[n];
		p[n]=find(p[n]);
		ran[n]=(ran[n]+ran[item])%2;
	}
	return p[n];
}
int half(int node)
{
	int mid;
	int tail=tot-1;
	int head=0;
	while(head<=tail)
	{
		mid=(tail+head)/2;
		if(dis[mid]==node)
		{
			return mid;
		}
		else if(dis[mid]>node)
		{
			tail=mid-1;
		}
		else
		{
			head=mid+1;
		}
	}
	return -1;
}
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		int m;
		scanf("%d",&m);
		tot=0;
		for(int i=0;i<m;i++)
		{
			po[i].id=i;
			scanf("%d%d%s",&po[i].st,&po[i].ed,po[i].oe);
			po[i].st--;
			dis[tot++]=po[i].st;
			dis[tot++]=po[i].ed;
		}
		//离散化
		sort(dis,dis+tot);
		tot=unique(dis,dis+tot)-dis;
		for(int i=0;i<=tot;i++)
		{
			p[i]=i;
			ran[i]=0;
		}
		int ans=0;
		for(int i=0;i<m;i++)
		{
			int st=half(po[i].st);
			int ed=half(po[i].ed);
			int ps=find(st);
			int pe=find(ed);
			if(ps==pe)
			{
				if(ran[st]==ran[ed]&&po[i].oe[0]=='o')
				{
					break;
				}
				if(ran[st]!=ran[ed]&&po[i].oe[0]=='e')
				{
					break;
				}
				ans++;
			}
			else
			{
				if(po[i].oe[0]=='o')
				{
					p[ps]=pe;
					ran[ps]=((ran[st]+ran[ed])%2+1)%2;
				}
				else
				{
					p[ps]=pe;
					ran[ps]=(ran[st]+ran[ed])%2;
				}
				ans++;
			}
		}
		printf("%d\n",ans);
	}
}

POJ1733 - Parity game - 并查集

时间: 2024-10-03 20:33:31

POJ1733 - Parity game - 并查集的相关文章

poj 1733 Parity game 并查集 离散化

点击打开链接题目链接 Parity game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6249   Accepted: 2413 Description Now and then you play the following game with your friend. Your friend writes down a sequence consisting of zeroes and ones. You cho

POJ 1733 Parity game (并查集)

Parity game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6816   Accepted: 2636 Description Now and then you play the following game with your friend. Your friend writes down a sequence consisting of zeroes and ones. You choose a conti

51nod 1204 Parity(并查集应用)

1204 Parity 题目来源: Ural 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 你的朋友写下一串包含1和0的串让你猜,你可以从中选择一个连续的子串(例如其中的第3到第5个数字)问他,该子串中包含了奇数个还是偶数个1,他会回答你的问题,然后你可以继续提问......你怀疑朋友的答案可能有错,或说同他之前的答案相互矛盾,例如:1 - 2 奇数,3 - 4 奇数,那么可以确定1 - 4 一定是偶数,如果你的朋友回答是奇数,就产生了矛盾.给出所有你朋友的

poj 1733 Parity game 【种类并查集+离散化】

Parity game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6767   Accepted: 2616 Description Now and then you play the following game with your friend. Your friend writes down a sequence consisting of zeroes and ones. You choose a conti

poj 1733 Parity game【哈希+并查集】

这道题题意我不想说了,但是有一个条件必须的说,就是1-2其实是0-2这条边,3-4是2-4这条边,但是困惑了好久,其他就是哈希给他一个地址 ,然后把注解看下方 #include <stdio.h> #include <string.h> #define maxx 10001 int par[maxx]; int rank[maxx]; void init() { for(int i=0;i<=maxx;i++) { rank[i]=0; par[i]=i; } } int f

poj1733(种类并查集+离散化)

题目链接: http://poj.org/problem?id=1733 题意: 输入n表示有一个长度为n的0,1字符串, m表示接下来有m行输入, 接下来的m行输入中x, y, even表示第x到第y个字符中间1的个数为偶数个, x, y, odd表示第x到第y个字符中间1的个数为奇数个, 若m句话中第k+1是第一次与前面的话矛盾, 输出k; 思路: 若x, y之间1的个数为偶数个, 那么1~x 与1~y中1的个数同奇偶性, 反之则异奇偶性, 我们可以将其理解为若输入x, y, even, 即

Poj 1733 Parity Game(离散化+并查集)

 题目大意:给出n个数字,m个区间内的数字和的奇偶性,询问从哪句话开始出现错误. 1.对于给定区间[l , r]的奇偶性,可以转化为[1. l-1]和[1, r]的奇偶性"关系",这样就可以用带权并查集来做了,权值为当前结点与根节点的奇偶性关系,每次查询如果l,r根结点相同,那么判断这句话是否正确,如果根节点不同,那么合并. 2.由于这道题数据量很大,但是查询只有m(m<=5000)所以要先将数据离散化.对于离散化,有两种方法,一种是考虑元素大小相对关系的,一种是不需要考虑元

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 names

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]