POJ1703 Find them, Catch them

来源:互联网 发布:大数据导论 编辑:程序博客网 时间:2024/06/04 19:22

题目链接:http://poj.org/problem?id=1703

大概思路:题目要确认的有三种结果,所以不能直接找出a的不同集合再与b合并。由于事先并不知道a、b是哪一派别的,所以开一个2*maxn大的数组,分成两个派别:a属于a,a属于a+maxn。每次执行D操作其实就是合并(a,b+maxn)和(a+maxn,b),最后判断a,b是否同一派别,a,b+maxn是否同一派别即可。

TLE了一次,cin和scanf的差异啊!

#include <iostream>#include<cstdio>using namespace std;const int MAXN=100005;int par[MAXN*2],hei[MAXN*2];int n,m,arr[MAXN];bool same(int x,int y);void unite(int x,int y);int find_root(int x);void init();int main(){    int t,a,b;    char ch;    cin>>t;    while(t--){        cin>>n>>m;        init();        int i=0;        while(m--){            //cin>>ch>>a>>b;            getchar();            scanf("%c%d%d",&ch,&a,&b);            if(ch=='D'){                unite(a,b+MAXN);                unite(b,a+MAXN);            }            if(ch=='A'){                //cout<<find_root(a)<<","<<find_root(b)<<endl;                if(same(a,b)) arr[i++]=0;                else if(same(a,b+MAXN)) arr[i++]=1;                else arr[i++]=2;            }        }        //for(int j=0;j<i;j++) cout<<arr[j]<<endl;        for(int j=0;j<i;j++){            switch(arr[j]){                case 0:cout<<"In the same gang.\n";break;                case 1:cout<<"In different gangs.\n";break;                case 2:cout<<"Not sure yet.\n";            }        }    }    return 0;}void init(){    for(int i=1;i<=n+MAXN;i++){        par[i]=i;        hei[i]=0;    }}int find_root(int x){    while(par[x]!=x){        x=par[x];    }    return x;}void unite(int x,int y){    x=find_root(x);    y=find_root(y);    if(x==y) return;    if(hei[x]<hei[y]) par[x]=y;    else{        par[y]=x;        if(hei[x]==hei[y]) hei[x]++;    }}bool same(int x,int y){    return find_root(x)==find_root(y);}


0 0