POJ 1703 Find them, Catch them

来源:互联网 发布:sql创建学生信息表 编辑:程序博客网 时间:2024/04/27 21:09

这题一开始看到的时候就感觉像用并查集,可是怎么分类我想了半天没弄明白,没办法就看别人的题解了。思路如下:如果a属于集团A,那么a+N就属于集团B。例如,如果是D a,b,那么显然a,b是属于不同的集团的。那么,a,b+N就属于相同的集团,a+N,b就属于相同的集团,这样就不用纠结a和b到底属于哪个集团,自己一开始就是陷在这里的。自己的思维还是有点僵化啊。剩下的就是把相同的集团成员合并在一起就行了。其实自己还是没有弄明白并查集的本质,长时间没有看,真的忘得差不多了。这题其实自己应该这样思考的:既然是并查集,就是把相同集合的成员合并在一起,但是怎么合并呢?D a,b给出的是不同集合的成员,肯定是不能合并的,于是就要想办法来合并。既然a,b不能合并,那a,b+N可以合并啊,这样不就解决问题了。

#include <cstdio>#include <cmath>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int N=100005;int father[2*N],deep[N*2];void init(){    int n=N*2;    for(int i=1;i<=n;i++)    {        father[i]=i;        deep[i]=0;    }}int _find(int x){    if(x!=father[x])        father[x]=_find(father[x]);    return father[x];}void _merge(int x,int y){    int a=_find(x);    int b=_find(y);    if(a!=b)    {        if(deep[a]<deep[b])            father[a]=b;        else        {            father[b]=a;            if(deep[a]==deep[b])                deep[a]++;        }    }}int main(){    int n,m,t,a,b;    scanf("%d",&t);    for(int i=1;i<=t;i++)    {        scanf("%d%d",&n,&m);        init();        char s[3];        for(int j=1;j<=m;j++)        {            scanf("%s%d%d",s,&a,&b);            if(s[0]=='A')            {                //printf("father[a]=%d,father[b]=%d\n",_find(a),_find(b));                if(_find(a)==_find(b))                    printf("In the same gang.\n");                else if(_find(a)==_find(b+N))                    printf("In different gangs.\n");                else                    printf("Not sure yet.\n");            }            else            {                _merge(a,b+N);//这里就是主旨思想的体现                _merge(a+N,b);            }        }    }    return 0;}


0 0
原创粉丝点击