HDU 1811 并查集

来源:互联网 发布:赢顺期货软件 编辑:程序博客网 时间:2024/06/06 00:49


思路:rateing高的点有指向rating低的点的有向边,用并查集将相同rating 的点放在同一集合内,以此建图。

CONFLICT的情况:同一集合内的点有边;有强连通。

UNCERTAIN的情况:在拓扑排序的过程中,每次操作入度为0的点的个数大于1 。

#include<cstdio>#include<vector>#include<cstring>#include<algorithm>#include<iostream>#include<cmath>#include<cstdlib>#include<queue>#define CLR(a,b) memset(a,b,sizeof(a))using namespace std;const int maxn = 10005;const int maxm = 20005;const int inf = 1e6 + 5;int n,m;int total;vector<int> G[maxn];int from[maxm],to[maxm];int len;int in[maxn];queue<int> que;bool uncertain,conflict;int sum;int par[maxn];void init_union(){CLR(par,-1);}int find(int x){while(par[x] >= 0) x = par[x]; return x;}void unite(int x,int y){x = find(x);y = find(y);if(x!=y) par[y] = x;}bool same(int x,int y){return find(x) == find(y);}void init(){    len = 0;sum = 0;total = 0;    uncertain = false;conflict = false;    CLR(in,-1);    for(int i=0;i<n;i++) G[i].clear();    while(!que.empty()) que.pop();    init_union();}void getTotal(){    for(int i=0;i<n;i++){        if(par[i] == -1){            total++;            in[i] = 0;        }    }    //cout<<total<<endl;}void build(){    for(int i=0;i<len;i++){        int u = from[i],v = to[i];        //cout<<u<<" "<<v<<endl;        u = find(u);v= find(v);        if(same(u,v)) conflict = true;        else {            G[u].push_back(v);            in[v]++;        }    }}void debug(){    for(int i=0;i<n;i++){        if(par[i] == -1){            cout<<in[i]<<" ";        }    }    cout<<endl;}void solve(){    getTotal();    build();    //debug();    int cnt = 0;    for(int i=0;i<n;i++){        if(in[i] == 0){            //cout<<i<<endl;            que.push(i);            cnt++;        }    }    if(cnt > 1) uncertain = true;    while(!que.empty()){        cnt = 0;        int u = que.front();que.pop();        sum++;        for(int i=0;i<G[u].size();i++){            int v = G[u][i];            in[v]--;            if(in[v] == 0){                que.push(v);cnt++;            }        }        if(cnt > 1) uncertain = true;    }    if(sum != total) conflict = true;    if(conflict) printf("CONFLICT\n");    else if(uncertain) printf("UNCERTAIN\n");    else printf("OK\n");}int main(){    while(~scanf("%d%d",&n,&m)){        init();        int a,b;        char op[5];        while(m--){            scanf("%d%s%d",&a,op,&b);            if(op[0] == '>'){                from[len] = a;                to[len] = b;                len++;            }else if(op[0] == '<'){                from[len] = b;                to[len] = a;                len++;            }else{                unite(a,b);            }        }        solve();    }    return 0;}


0 0
原创粉丝点击