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

题目链接: [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;
}


你可能感兴趣的:(拓扑排序,并查集)