您的位置:首页 > 其它

poj 1703 Find them, Catch them(并查集)

2012-03-07 13:29 435 查看
【题目大意】:有n个黑帮团伙成员,且有两个帮派。现在D(x,y)表示我们已知x,y不属于同意个帮派。A(x,y)表示查询输出x,y之间的关系。给出m个操作D或A,求答案。

Not sure yet.表示不能确定关系 In different gangs. 不在同一个帮派 In the same gang.在同一帮派


【解题思路】:看完题目,知道是并查集,但是用一个集合在纸上怎么样都够造不出解法。为了让sample更清晰,把集合copy了一次,却无意中发现了解法。

1
5 5
A 1 2
D 1 2
A 1 2
D 2 4
A 1 4    以sample为例。



把表示x,y不同的操作全部连边,注意是上下连边,即每一次操作都会连两组边,也就是说把集合进行了合并操作。查询时,对于x,y两个查询其是否在同一集合(这里的x,y都是同侧的x,y),则在同一帮派。
若x,y分别位于上下两部分,且其在同一个集合,则在不同的帮派。其余无法确定。


有了以上思路,用并查集就瞬秒。这道题感觉纯属运气,yy成分居多。因为自己不怎么搞图论,队友听完跟我说很像2-sat。所以,今晚有空不如学学吧。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <queue>

using namespace std;

int n, m;
int father[200050];

void make_set(){
for(int i=1; i<=n*2; i++){
father[i]=i;
}
}

int find_set(int x){
if(x!=father[x])
father[x]=find_set(father[x]);
return father[x];
}

void union_set(int x,int y){
x=find_set(x);
y=find_set(y);
if(x==y) return;
father[y]=x;
}

int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
make_set();
while(m--){
char c[2];
int x,y;
scanf("%s%d%d",c,&x,&y);
if(c[0]=='D'){
union_set(x,y+n);
union_set(y,x+n);
}
if(c[0]=='A'){
if(find_set(x)==find_set(y))
cout << "In the same gang." << endl;
else if(find_set(x)==find_set(y+n) || find_set(y)==find_set(x+n))
cout << "In different gangs." << endl;
else
cout << "Not sure yet." << endl;
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: