您的位置:首页 > 其它

HDU-1811 Rank of Tetris

2015-04-21 20:08 363 查看
拓扑排序难题。

对于相同排名的玩家,我们将他们组成一个集合。这可以用并查集实现。

然后将并查集看成一个点,将所有大于小于的关系转换成集合中的关系,这个过程就可以判断方案是否冲突了。

然后拓扑排序求排名,顺便也就可以判断结果是否唯一了。

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cctype>
#include <queue>
#include <cstring>
#include <queue>
using namespace std;
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define travel(x) for(edge *p=fir[x]; p; p=p->n)
#define maxn 10009
#define maxm 20009
#define clr(x, c) memset(x, c, sizeof(x))

struct edge{int x, y, z; edge *n;} e[maxm], *fir[maxn], *pt;
int n, m, a, b, v[maxn], h[maxn], die;
char s[10];
inline void Init(){pt=e; clr(fir, 0); clr(v, 0); die=0; rep(i, 0, n-1) h[i]=i;}
inline void Add(int x, int y, int z){pt->x=x, pt->y=y, pt->z=z, pt++;}
int Find(int x){return x==h[x]?x:h[x]=Find(h[x]);}
int main()
{
while (~scanf("%d%d", &n, &m))
{
Init();
rep(i, 0, m-1)
{
scanf("%d%s%d", &a, s, &b);
if (s[0]=='=') Add(max(a, b), min(a, b), 0);
else if (s[0]=='>') Add(a, b, 1);
else if (s[0]=='<') Add(b, a, 1);
}
rep(i, 0, m-1) if (!e[i].z)
Find(e[i].x)!=Find(e[i].y) ? h[h[e[i].x]]=h[e[i].y] : i=i;
rep(i, 0, n-1) Find(i);

priority_queue<int>q;
rep(i, 0, m-1) if (e[i].z) e[i].x=h[e[i].x], e[i].y=h[e[i].y];
rep(i, 0, m-1) if (e[i].z) v[e[i].y]++;
rep(i, 0, m-1) if (e[i].z) e[i].n=fir[e[i].x], fir[e[i].x]=&e[i];
rep(i, 0, n-1) if (h[i]==i && !v[i]) q.push(i);
while (!q.empty())
{
if (q.size()>1) die=2;
int x=q.top(); q.pop(); v[x]=-1;
travel(x) if (p->z) {v[p->y]--; if (!v[p->y]) q.push(p->y);}
}
rep(i, 0, n-1) if (h[i]==i && v[i]!=-1) {die=1; break;}
if (die==0) printf("OK\n");
else if (die==1) printf("CONFLICT\n");
else printf("UNCERTAIN\n");
}
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: