题目链接:
[HDU 1811]Rank of Tetris[拓扑排序][并查集]
题意分析:
给出的关系中是否存在矛盾,是否无法确定关系?两者都有,输出"矛盾"即可。
解题思路:
排名大小关系,很容易想到拓扑排序。问题在于,什么情况下是不确定的?当处理队列中有多个点时,就是不能确定的情况,因为后继操作可以选择多个不同的开始。需要注意的是本题存在等于的情况,这时需要将相等的两者合并,合并之后再开始建边,使得信息共享。
个人感受:
不知道怎么确定不确定关系。。。。心塞。
具体代码如下:
#include<cstdio>
#include<iostream>
#include<queue>
using namespace std;
const int INF = 0x7f7f7f7f;
const int MAXN = 1e4 + 111;
vector<int> G[MAXN];
int p[MAXN], in[MAXN], a[MAXN], b[MAXN];
char cmp[2 * MAXN];
int find(int x)
{
return x == p[x] ? x : p[x] = find(p[x]);
}
void unite(int x, int y)
{
x = find(x), y = find(y);
if (x != y) p[x] = y;
}
int main()
{
int n, m;
while (~scanf("%d%d", &n, &m))
{
for (int i = 0; i < n; ++i) G[i].clear(), p[i] = i, in[i] = 0;
int sum = n;
for (int i = 0; i < m; ++i)
{
scanf("%d %c %d", &a[i], &cmp[i], &b[i]);
if (cmp[i] == '=') unite(a[i], b[i]), --sum; // 相等的看作一个整体
}
bool conf = 0, uncer = 0;
for (int i = 0; i < m; ++i)
{
if (cmp[i] == '=') continue;
int x = find(a[i]), y = find(b[i]);
if (x == y) conf = 1; // 等级相同却又存在绝对大小关系,矛盾
if (cmp[i] == '>') G[x].push_back(y), ++in[y];
else G[y].push_back(x), ++in[x];
}
queue<int> q;
for (int i = 0; i < n; ++i)
{
int cur = find(i);
if (!in[cur] && p[cur] == i) q.push(cur);
}
while (q.size())
{
int cur = q.front(); q.pop(); --sum;
if (q.size()) uncer = 1; // 多个点可以操作,无法确定哪一个
for (int i = 0; i < G[cur].size(); ++i)
{
int v = G[cur][i];
if (--in[v] == 0) q.push(v);
}
}
if(sum > 0 || conf) printf("CONFLICT\n");
else if(uncer) printf("UNCERTAIN\n");
else printf("OK\n");
}
return 0;
}
本文解析了HDU1811竞赛题目的解决方案,通过使用拓扑排序来判断给出的排名关系是否存在矛盾或不确定性,并介绍了如何处理相等排名的情况。

554

被折叠的 条评论
为什么被折叠?



