代码抄自:hdu1811 - Ice_Crazy的专栏 - 博客频道 - CSDN.NET
题目大意:给你一些大小关系,让你判断是否能够使所有元素有序排列起来。如果可以输出OK,要是有冲突输出CONFLICT,在没有冲突的条件下如果关系不满足全部排序,输出UNCERTAIN。
Eage类中的from代表较大值x,to代表较小值y,next是x的下一个直接下属yi所组成的Eage在ee数组中的编号,next为-1时代表遍历完全所有的yi。
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 10010;
const int maxm = 20010;
int n, m;
int father[maxn], in[maxn], ans;
struct Eage
{
int from, to, next;
}ee[maxm];
int head[maxn], a[maxm], b[maxm], tot;
char sh[maxm][4];
//x为较大值,y为较小值
void add(int x, int y)
{
ee[tot].from = x;
ee[tot].to = y;
//上一次x作为较大值时所存边的编号
ee[tot].next = head[x];
head[x] = tot++;
}
int find_father(int k)
{
if(father[k] == k)
return k;
return father[k] = find_father(father[k]);
}
int Get_Map()
{
int fa, fb;
for(int i = 0; i < n; i++)
father[i] = i;
for(int i = 0; i < m; i++)
{
scanf("%d%s%d", &a[i], sh[i], &b[i]);
//相等合并为一点
if(sh[i][0] == '=')
{
fa = find_father(a[i]);
fb = find_father(b[i]);
father[fb] = fa;
}
}
memset(head, -1, sizeof(head));
memset(in, 0, sizeof(in));
//father数组一步到位
for(int i = 0; i < n; i++)
find_father(i);
tot = 0;
for(int i = 0; i < m; i++)
{
//并点后发现关系发生矛盾,直接输出矛盾
if(father[a[i]] == father[b[i]] && sh[i][0] != '=')
return 1;
if(sh[i][0] == '>')
{
add(father[a[i]], father[b[i]]);
in[father[b[i]]]++;
}
if(sh[i][0] == '<')
{
add(father[b[i]], father[a[i]]);
in[father[a[i]]]++;
}
}
return 0;
}
int Topsort()
{
int flag, tmp, now, tot2;
queue<int> q;
tot = flag = tmp = 0;
for(int i = 0; i < n; i++)
{
if(father[i] == i)
{
tot++;
//入度为0,即rating最大的点,环上的点入度均不为0
if(!in[i])
{
tmp++;
q.push(i);
}
//rating最大的点不止一个,但还是有可能会有矛盾关系
if(tmp > 1)
flag = 2;
}
}
int k = 0, v;
while(!q.empty())
{
now = q.front();
q.pop();
//记录有多少条合法边
k++;
in[now]--;
tmp = 0;
for(int j = head[now]; j != -1; j = ee[j].next)
{
v = ee[j].to;
in[v]--;
if(!in[v])
{
//直接下属不止一个,可能是不能确定,但也有可能剩下的关系会矛盾
tmp++;
//为了检测删点是否有环
q.push(v);
}
}
//删点之后剩余的rating最大点不止一个
if(tmp > 1)
flag = 2;
}
//合法边与总边数不等
if(k < tot)
flag = 1;
return flag;
}
int main()
{
// freopen("1811.in", "r", stdin);
while(~scanf("%d%d", &n, &m))
{
ans = Get_Map();
if(!ans)
ans = Topsort();
if(!ans)
puts("OK");
else if(ans == 1)
puts("CONFLICT");
else
puts("UNCERTAIN");
}
return 0;
}