您的位置:首页 > 其它

poj 1703 Find them,Catch them

2014-07-16 13:44 393 查看
说一下题意:

某市公安局决定要将该市的两个犯罪团伙连根拔起,一个是神龙帮,另外一个是灵蛇帮。目前的问题是,给你两个罪犯,判断他们各自属于哪一个帮派,你只能根据你已经

知道的不完整的信息来判定。

假设该市有N个罪犯,编号是1到N,当然,他们中不是神龙帮的就是灵蛇帮的,你将得到关于他们的M条信息。

(1)D a b

a, b是两个罪犯的编号,并且他们属于不同的帮派

(2)A a b

a, b 是两个罪犯的编号,这条信息是向你询问 这两个罪犯是否属于同一个帮派。

处理问题的关键就是 处理好并查操作时,节点之间的关系的建立和更新。

Step 1: 解题前首先要确定用某种方式来表示节点与根节点的关系,例如可以用 0 ,1分别标记某一个节点与树根的同异帮关系。据此可以写好并查集的查找函数

Step 2: 可以先认为每个节点都是树根且都与自身同帮派,据此初始化标记变量。

Step 3:对每组输入数据进行处理,若两个节点的根节点不同,若A操作,则无法确认两者的关系,若D操作,则合并两个节点所在树且更新节点关系;

若两个节点的根节点相同,则根据这两个节点与根节点的关系来判定这两个节点的关系,并给出相应的输出。

附上代码:

#include <iostream>

#include <stdio.h>

#include <string.h>

#define N 1000100

using namespace std;

int f
,c
,key;

int find(int x)

{

if(f[x]==x)return x;

int t=f[x];

f[x]=find(f[x]);

c[x]=(c[x]+c[t])%2;

return f[x];

}

void make(int a,int b)

{

int f1=find(a);

int f2=find(b);

if(f1!=f2)

{

f[f1]=f2;

if((c[a]+c[b])%2==0)

c[f1]=1;

}

else

{

if((c[a]+c[b])%2==0)

key=1;

else

key=2;

}

}

int main()

{

int n,m,t;

scanf("%d",&t);

while(t--)

{

scanf("%d%d",&n,&m);

memset(c,0,sizeof(c));

for(int i=1;i<=n;i++)

f[i]=i;

char s[10];

int a,b;

for(int i=0;i<m;i++)

{

scanf("%s%d%d",s,&a,&b);

key=0;

if(s[0]=='A')

{

int fa=find(a);

int fb=find(b);

if(fa!=fb)

printf("Not sure yet.\n");

else

{

make(a,b);

if(key==2)

printf("In different gangs.\n");

else if(key==1)

printf("In the same gang.\n");

}

}

else if(s[0]=='D')

{

make(a,b);

}

}



}

return 0;

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