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

来源:互联网 发布:php开发环境搭建教程 编辑:程序博客网 时间:2024/06/16 02:40

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=1811

题意

有个rating系统,每个人的rating有高有低,给定n个人之间m条高低或等于关系。
判断:
1.是否能确定每个人之间的高低情况
2.是否有冲突
3.高低情况不确定
注意:如果信息中同时包含冲突且信息不完全,也算冲突

思路

并查集缩点,将分数相同的缩点。拓扑排序即可,如果某次出现两个或两个以上的入度为0的点,则不能确定。如果出现环了,即是冲突。

#include<cstdio>#include<queue>#include<iostream>#include<vector>#include<map>#include<cstring>#include<string>#include<set>#include<stack>#include<algorithm>#define cle(a) memset(a,0,sizeof(a))#define inf(a) memset(a,0x3f,sizeof(a))#define ll long long#define Rep(i,a,n) for(int i=a;i<=n;i++)using namespace std;#define INF2 9223372036854775807llconst int INF = ( 2e9 ) + 2;const ll maxn = 10010;int f[maxn];int In[maxn];vector<int> g[maxn];struct edge{    int u,v;};vector<edge> e;int Find(int x){    return f[x]==x?x:f[x]=Find(f[x]);}void Union(int x,int y){    int xx=Find(x);    int yy=Find(y);    if(xx!=yy)        f[xx]=yy;}int topsort(int n){    int cnt=0,tot=0,unc=0;    int vis[maxn];    priority_queue<int> q;    memset(vis,0,sizeof(vis));    for(int i=0; i<n; i++)if(f[i]==i)tot++;    for(int i=0; i<n; i++)        if(In[Find(i)]==0&&!vis[Find(i)])        {            vis[Find(i)]=1;            q.push(Find(i));            cnt++;        }    if(cnt>=2)        unc = 1;        cnt=0;    while(!q.empty())    {        int u=q.top();        q.pop();        int f=0;        for(int i=0,L=g[u].size(); i<L; i++)        {            int v=g[u][i];            In[v]--;            if(In[v]==0)            {                q.push(v);                f++;            }        }        if(f>=2)unc=1;        cnt++;    }    if(cnt==tot)    {        if(unc)return 1;        else return 2;    }    else return 3;}int main(){    int n,m;    while(~scanf("%d%d",&n,&m))    {        memset(In,0,sizeof(In));        for(int i=0;i<=n;i++)g[i].clear();        for(int i=0;i<=n;i++)f[i]=i;        e.clear();        for(int i=0; i<m; i++)        {            int u,v;            char op;            scanf("%d %c %d",&u,&op,&v);            if(op=='=')                Union(u,v);            else if(op=='>')                e.push_back(edge{u,v});            else                e.push_back(edge{v,u});        }        for(int i=0,L=e.size();i<L;i++)        {            int u=e[i].u,v=e[i].v;            g[Find(u)].push_back(Find(v));            In[Find(v)]++;        }        int flag=topsort(n);        if(flag==1)        printf("UNCERTAIN\n");        else if(flag==2)        printf("OK\n");        else        printf("CONFLICT\n");    }}
阅读全文
0 0