【并查集+拓扑排序】【HDU1811】【Rank of Tetris】

来源:互联网 发布:深入理解linux 编辑:程序博客网 时间:2024/05/21 08:43

题意:给你3种关系 A=B,A>B,A<B 问是否排名方式唯一,或者存在矛盾


解 1.读入数据先处理 =号 用并查集的祖先作为代表元素,其他儿子节点都等于跟这个点重叠。 再读入 ‘<’ ‘>’ 来建图进行拓扑排序

 

2.将所有入度为0的点加入队列,再从队列中取出一个点,对其所连的边的入度进行-1,如果使入度=0则加入队列,直至队列为空


3.如果进入队列的点 小于 总点数(非N,N-重点) 则有矛盾

如果有队列中元素>=2的时刻 则证明不存在唯一的排名方式 

其余 OK;


代码如下:

/*WA1 调试数据2 20 = 10 = 1错误输出 CONFLIET正确输出 OK错误原因 if(tot<N) printf("CONFLICT\n"); 忘记了重点(合并的点),所以总共要遍历的点少于N*///Warning 虽然这里没必要 不过还是要的记得清空队列//结果   Run ID     Submit Time  Judge StatusPro.IDExe.TimeExe.MemoryCode Len.LanguageAuthor//结果   133067452015-03-31 21:40:45  Accepted181131MS      1972K      2378 BC++        ZHOU#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <ctime>#include <algorithm>#include <iostream>#include <sstream>#include <string>#include<queue>#define oo 0x13131313const int maxn=10005;int N,M;struct fa{    int a,b;    char c;};fa A[4*maxn];struct Edge{                int to;                Edge *next;           };struct Node{                int num;                Edge *first;           };Edge E[maxn*4],*EE=E+1;Node Graph[maxn];int father[maxn];using namespace std;int find(int x){    if(x!=father[x])    father[x]=find(father[x]);    return father[x];}void Union(int a,int b){    int aa=find(a),bb=find(b);    if(aa!=bb) father[aa]=bb;}void init(){    freopen("a.in","r",stdin);    freopen("a.out","w",stdout);}void Link(int u,int v){    EE->to=v,EE->next=Graph[u].first,Graph[u].first=EE++;    Graph[v].num++;}void CLEAR(){    memset(Graph,0,sizeof(Graph));    EE=E+1;    for(int i=0;i<=maxn-1;i++)        father[i]=i;}void input(){    CLEAR();    for(int i=1;i<=M;i++)    {    scanf("%d %c %d\n",&A[i].a,&A[i].c,&A[i].b);    if(A[i].c=='=') Union(A[i].a,A[i].b);    }    for(int i=1;i<=M;i++)    {        if(A[i].c=='<') Link(find(A[i].a),find(A[i].b));        else if(A[i].c=='>') Link(find(A[i].b),find(A[i].a));    }}void solve(){    int ok=1;    int tot=0;    int kk=0;    queue <int> Q;    while(!Q.empty()) Q.pop();    for(int i=0;i<N;i++)    if(father[i]==i)        {        kk++;        if(Graph[i].num==0)          Q.push(i);        }    while(!Q.empty())    {        if(Q.size()>=2) ok=0;        int t=Q.front();Q.pop();tot++;        for(Edge *p=Graph[t].first;p;p=p->next)        {            Graph[p->to].num--;            if(Graph[p->to].num==0) Q.push(p->to);        }    }    if(tot<kk) printf("CONFLICT\n");    else if(ok==0) printf("UNCERTAIN\n");    else printf("OK\n");}int main(){   // init();    while(cin>>N>>M)    {        input();        solve();    }    return 0;}



0 0