HDU-1811-Rank of Tetris
这道题是拓扑排序+并查集~
中文题面就不过多描述啦~
题目思路:我们把rating相等的两个人放在同一个集合里,
然后开始逐一判断:
如果碰到‘=’直接continue;
如果碰到’>’ 或者’<’;
但是他们祖先根结点相等的话。就说明出现了错误。标记就行。
如果A的rating > B的rating;
即A > B;
我们就把A和B连一条边。B的入度++;
这个地方的连边和LCA一样的。
head[]记录对应的edge[]的哪一个。
详细解释参考LCA的代码解释部分:
https://blog.csdn.net/qq_44624316/article/details/105165911
否则A的入度++;
完成上述操作之后开始bfs;
我们把入度为0的并且祖先根结点为其本身的加入队列。
之后开始判断。
因为输入的数据有可能存在数据不足的情况。所以如果队列中元素的个数>=2的话就说明数据不足。不足以判断。标记即可。
之后开始一条线的遍历。
想清楚了就比较容易啦~
代码部分:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
struct node
{
int v;
int next;
}edge[N];
struct Node
{
int a, b;
char c;
}h[N];
int fa[N];
int head[N];
int in[N];
int n, m;
int edgenum;
int sum;
int flag0, flag1;
priority_queue<int> q;
void init()
{
while (!q.empty())
{
q.pop();
}
for (int i = 0; i <= n; i++)
{
fa[i] = i;
head[i] = -1;
in[i] = 0;
}
edgenum = 0;
sum = n;
flag0 = flag1 = 0;
}
int find(int x)
{
if (x != fa[x])
{
return fa[x] = find(fa[x]);
}
return fa[x];
}
void mix(int x, int y)
{
int xx = find(x);
int yy = find(y);
if (xx != yy)
{
fa[yy] = fa[xx];
}
}
void add(int x, int y)
{
edge[edgenum].v = y;
edge[edgenum].next = head[x];
head[x] = edgenum++;
}
void bfs()
{
for (int i = 0; i < n; i++)
{
int t = find(i);
if (!in[t] && fa[t] == i)
{
q.push(t);
}
}
while (!q.empty())
{
int now = q.top();
q.pop();
sum--;
if (!q.empty())
{
flag1 = 1;
}
for (int i = head[now]; i != -1; i = edge[i].next)
{
if (--in[edge[i].v] == 0)
{
q.push(edge[i].v);
}
}
}
}
int main()
{
while (~scanf ("%d%d", &n, &m))
{
init();
for (int i = 0; i < m; i++)
{
scanf ("%d %c %d", &h[i].a, &h[i].c, &h[i].b);
if (h[i].c == '=')
{
sum--;
mix(h[i].a, h[i].b);
}
}
for (int i = 0; i < m; i++)
{
if (h[i].c == '=')
{
continue;
}
int x = find(h[i].a);
int y = find(h[i].b);
if (x == y)
{
flag0 = 1;
}
if (h[i].c == '>')
{
add(x, y);
in[y]++;
}
else
{
add(y, x);
in[x]++;
}
}
bfs();
if (flag0 || sum > 0)
{
cout << "CONFLICT\n";
}
else if (flag1)
{
cout << "UNCERTAIN\n";
}
else
{
cout << "OK\n";
}
}
return 0;
}