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

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


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

 

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


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

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

其余 OK;


代码如下:

/*
WA1 调试数据
2 2
0 = 1
0 = 1
错误输出 CONFLIET
正确输出 OK

错误原因 if(tot<N) printf("CONFLICT
"); 忘记了重点(合并的点),所以总共要遍历的点少于N
*/
//Warning 虽然这里没必要 不过还是要的记得清空队列
//结果   Run ID	     Submit Time	  Judge Status	Pro.ID	Exe.Time	Exe.Memory	Code Len.	Language	Author
//结果   13306745	2015-03-31 21:40:45	  Accepted	1811	31MS	      1972K	      2378 B	C++	        ZHOU

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include<queue>
#define oo 0x13131313
const 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
",&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
");
    else if(ok==0) printf("UNCERTAIN
");
    else printf("OK
");
}
int main()
{
   // init();
    while(cin>>N>>M)
    {
        input();
        solve();
    }
    return 0;
}



原文地址:https://www.cnblogs.com/zy691357966/p/5480399.html