您的位置:首页 > 其它

POJ 1733 parity game (hash离散+并查集)

2014-03-24 04:03 351 查看
题目要求输入的长度less or equal 1000000000,但是实际的问题数却小于5000

所以我们考虑hash离散化。

解题思路如下:



我们为每一个输入的点,建立struct,内包含2个成员,father指向父亲node,relationship表示与父节点的关系

于是我们有:

===================

图1,我们执行的是查找操作,假设B与A是even关系,C与B是odd关系,那么查找压缩路径后,可以发现A与C是odd关系,于是我们有:
C.relationship=B.relationship^C.relationship;

对于图2,我们执行的是合并操作,一样可以通过假设举例找出关系,其中xor为输入的B与D的关系

C.relationship=B.relationship^D.relationship^xor;

=================

#include<iostream>
using namespace std;
#define N 5005

/*
hash+离散化===================================================================================
*/
struct node
{
int val;
int next;
}E
;
int v
, cnt=0;
int hash_1(int n)
{
int k=n%N;
for(int e=v[k];e!=-1;e=E[e].next)
{
if(E[e].val==n)
return e;
}
E[cnt].next=v[k];
E[cnt].val=n;
v[k]=cnt++;
return cnt-1;
}
/*================================================================================================*/
/*
并查集
*/

struct num
{
int father;
int relationship;
}num
;

void make_set(int n)
{
for(int i=0;i<n;i++)
{
num[i].father=i;
num[i].relationship=0;  //even
}
}

int find_set(int x)
{
if(x==num[x].father)
return x;
else
{
int  temp=num[x].father;
num[x].father=find_set(num[x].father);
num[x].relationship=num[temp].relationship^num[x].relationship; //xor
return num[x].father;
}
}

void union_1(int x,int y,int a,int b,int xor)
{
num[y].father=x;
num[y].relationship=num[a].relationship^num[b].relationship^xor;
}

void main()
{
int xor,M1,M2,a,b,a1,b1;
char op[7];
int sum;
bool flag;
memset(v,-1,sizeof(v));
while(cin>>M1>>M2)
{
flag=true;
make_set(N);
sum=0;
for(int i=0;i<M2;i++)
{
cin>>a>>b>>op;
a--;//半开区间(a,b],注意a--
if(op[0]=='o')
xor=1;
else xor=0;
a=hash_1(a);
b=hash_1(b);
a1=find_set(a);
b1=find_set(b);
if(a1==b1)
{
if(num[a].relationship^num[b].relationship!=xor)
flag=false;
else
{if(flag)
sum++;
}

}
else
{
if(flag)
{
sum++;
}
union_1(a1,b1,a,b,xor);
}
}
cout<<sum<<endl;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: