您的位置:首页 > 其它

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

2015-04-24 22:35 330 查看
本题的主要问题就是给定m个名次大小关系,问每个人的名次是否能确定下来。

这个问题可以用topsort解决,名次发生冲突即找不到topsort结果。由于关系太少导致的名次不能确定直接在topsort过程中检测入度为0的点是否每次出现2个以上(即t-h>=2)那么说明拓扑排序结果不止一种,名次不能确定

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

const int N = 11000;
const int M = 22000;
int poi;
int head
;
struct Edge
{
    int u,v,next;
}es[M];
int n,m;
int f
;
int getf(int x){return f[x]==x? x:f[x]=getf(f[x]); }
void Merge(int a,int b)
{
    int f1=getf(a),f2=getf(b);
    if(f1==f2) return ;
    f[f2]=f1;
    poi--;
}
int q
,h,t,cnt;
int in
;
int a
,b
;
char s
[5];
inline void add_edge(int u,int v)
{
    es[++cnt].u=u;
    es[cnt].v=v;
    es[cnt].next=head[u];
    head[u]=cnt;
}
bool vis
;
void topsort()
{
    h=t=0;
    bool flagc=0,flagu=0;
    for(int i=1;i<=cnt;i++)
    {
        int u=es[i].u;
        int v=es[i].v;
        if(u==v) flagc=1;
        in[v]++;
    }
    for(int i=1;i<=n;i++)
    {
        int v;
        if(vis[v=getf(i)]) continue;
        if(in[v]==0) q[t++]=v,vis[v]=1;
    }
    if(t>1) flagu=1;
    while(h<t)
    {
        int u=q[h++];
        for(int i=head[u];~i;i=es[i].next)
        {
            int v=getf(es[i].v);
            in[v]--;
            if(in[v]==0) q[t++]=v;
        }
        if(t-h>1) flagu=1;
    }
    if(t<poi) flagc=1;
    if(flagc) puts("CONFLICT");
    else if(flagu) puts("UNCERTAIN");
    else puts("OK");
}
void ini()
{
    memset(head,-1,sizeof(head));
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++) f[i]=i;
    h=t=cnt=0;
    memset(in,0,sizeof(in));
    poi=n;
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        ini();
        for(int i=1;i<=m;i++)
        {
            scanf("%d%s%d",&a[i],s[i],&b[i]);
            a[i]++,b[i]++;
            if(s[i][0]=='=')
            {
                Merge(a[i],b[i]);
            }
        }
        for(int i=1;i<=m;i++)
        {
            if(s[i][0]=='=')continue;
            int u=getf(a[i]);
            int v=getf(b[i]);
            if(s[i][0]=='<') add_edge(u,v);
            else add_edge(v,u);
        }
        topsort();
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: