HDU1811 Rank of Tetris(并查集+拓扑排序)

来源:互联网 发布:詹姆斯数据 编辑:程序博客网 时间:2024/05/17 03:56

思路:利用并查集缩点,把相等的点看成一个,然后他们的父亲的号,就相当于他们的新号

#include<cstdio>#include<iostream>#include<algorithm>#include<cmath>#include<set>#include<map>#include<string>#include<cstring>#include<stack>#include<queue>#include<vector>#include<cstdlib>#define lson (rt<<1),L,M#define rson (rt<<1|1),M+1,R#define M ((L+R)>>1)#define cl(a,b) memset(a,b,sizeof(a));#define LL long long#define P pair<int,int>#define X first#define Y second#define pb push_back#define fread(zcc)  freopen(zcc,"r",stdin)#define fwrite(zcc) freopen(zcc,"w",stdout)using namespace std;const int maxn=100005;const int inf=1<<28;int in[maxn];vector<int> G[maxn];int f[maxn];int find(int x ){    return x==f[x]?x:f[x]=find(f[x]);}void Union(int x,int y){    x=find(x);y=find(y);    f[x]=y;}int topo(int n){    stack<int> q;    for(int i=0;i<n;i++){        int t=find(i);        if(in[t]==0&&f[t]==i)//f[t]==i,是筛选这个集合里只要取出一个        q.push(t);    }    int cnt=0;    while(!q.empty()){        int t=q.top();q.pop();        cnt++;        for(int i=0;i<G[t].size();i++){            int v=G[t][i];            if((--in[v])==0)q.push(v);        }    }    return cnt;}struct node{    int x,y;    char c;}p[maxn];int out[maxn];int main(){    int n,m;    while(~scanf("%d%d",&n,&m)){        for(int i=0;i<=n;i++){            G[i].clear();            f[i]=i;            in[i]=out[i]=0;        }        char s[2];int x,y;        int sum=n;        for(int i=0;i<m;i++){            scanf("%d%s%d",&p[i].x,s,&p[i].y);            p[i].c=s[0];            if(s[0]=='='){                sum--;                Union(p[i].x,p[i].y);            }        }        bool ok=false;        for(int i=0;i<m;i++){            if(p[i].c=='=')continue;            int x=find(p[i].x);            int y=find(p[i].y);            if(x==y)ok=true;///说明信息冲突            if(p[i].c=='>'){                G[x].pb(y);                in[y]++;out[x]++;            }            else {                G[y].pb(x);                in[x]++;out[y]++;            }        }        ///判断出度为0 的点不能多于两个        int num=0;        bool ok3=false;        for(int i=0;i<n;i++){            int t=find(i);            if(out[t]==0&&f[t]==i)num++;        }        if(num>1)ok3=true;        ///--------------------        ///拓扑排序检测是否有环        bool ok2;        if(topo(n)<sum)ok2=true;        else ok2=false;        if(ok2||ok){            puts("CONFLICT");        }        else if(ok3){            puts("UNCERTAIN");        }        else {            puts("OK");        }    }    return 0;}
0 0