Parity game POJ - 1733

题意:给你一个n,表示有一串长为n的由0和1组成的串,之后给你m次操作 a b op ,其中op表示是even 表示a到b的和是偶数,o表示的是奇数,现在问你在第几次操作的时候你发现他和之前矛盾。

前置技能:讲道理知道题的所有做法和公式都和之前的带权并查集一样,手推出如何压缩路径,如何合并,如何查找矛盾这题就可解了,唯一不同的是,这道题的区间有1到1000000000,需要离散化,我在这里讲一下离散化吧

比如当你的区间只有 1~9,1000~2000,10000~40000 ,的时候你会发现中间有好多我们是空着的用不到的,那我们把这些区间端点存一下拍一下序之后 映射一下 映射的值是他是他在当前序列的排名,1映射值就是1,9映射值就是2,1000映射值就是3,之后我们把区间变成了 1~2 , 2 ~3 ,3 ~4这种完全连续的区间了,省下了大量的空间。

思路:和前几题一样,没差了,就是离散需要学一下,上代码吧 ,代码上讲的很清楚:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <map>
#include <iostream>
using namespace std;
const int maxn = 50000+10;
int p[maxn],Rank[maxn],ans , num[maxn];
struct node
{
	int u,v,w;
}edg[maxn];

int getf(int x)
{
	if(p[x] == x)
	{
		return x;
	}
	int t = p[x];
	p[x] = getf(p[x]);
	Rank[x] = (Rank[x] + Rank[t]) % 2;
	return p[x];
}
void init()
{
	for(int i = 0 ; i < maxn ; i++)
	{
		p[i] = i;
		Rank[i] = 0;
		num[i] = 0; 
	}
}
int main()
{
	int n,m;
	char op[10];
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		int cnt = 0;
		init();
		ans = 0 ;
		for(int i = 0 ; i < m ;i++)
		{
			scanf("%d%d%s",&edg[i].u,&edg[i].v,op); 
			if(op[0] == 'e') edg[i].w = 0;
			else edg[i].w = 1;
			edg[i].u--;
			num[cnt++] = edg[i].u;
			num[cnt++] = edg[i].v;//我们把区间存起来
		}
		sort(num,num+cnt);//按照从小到大去排序 
		int flag = 0 ;
		cnt = unique(num,num+cnt) - num;//去掉重复元素 
		for(int i = 0 ; i < m ; i++)
		{
			int nx = lower_bound(num,num+cnt,edg[i].u) - num;//二分去找当前的区间左端点在num数组中的排名 
			int ny = lower_bound(num,num+cnt,edg[i].v) - num;//二分去找当前的区间右端点在num数组中的排名  
			int dx = getf(nx);
			int dy = getf(ny);
			if(dx != dy)
			{
				p[dy] = dx;
				Rank[dy] = (Rank[nx] - Rank[ny] + edg[i].w + 2) % 2;
			}
			else 
			{
				if((Rank[ny] - Rank[nx] + 2)%2 != edg[i].w)//如果不一样就跳出了 
				{
					flag = 1;
					printf("%d\n",i);
					break;
				}
			}
		}
		if(!flag) printf("%d\n",m);
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值