BAPC preliminaries 2016 B. Chess Tournament


一句话题解:

先把相等的点缩小成一个点(并入一个集合),然后在通过大小关系处理剩余点(集合)之间的关系(拓扑排序)

#include
using namespace std;
#define ll long long
#define fastio ios::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL)
const int maxn = 250000 + 1;
const ll inf = 1e17;
ll mod = 1e9 + 7;

int fa[50010];

struct edge {
    int to, next;
}e[maxn << 1];

int head[maxn], edge_cnt = 0;

inline void add(int from, int to)
{
    e[++edge_cnt] = { to,head[from] };
    head[from] = edge_cnt;
}

int anc(int x)
{
    return x == fa[x] ? x : fa[x] = anc(fa[x]);
}

void uni(int x, int y)
{
    fa[anc(x)] = anc(y);
}

struct dx {
    int a, b;
    char c;
};

vectorop;

int ru[maxn];

int main()
{
    //freopen("C:\\1.in", "r", stdin);
    fastio;
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < n; i++)
        fa[i] = i;
    memset(head, -1, sizeof(head));
    while (m--)
    {
        int a, b;
        char c;
        cin >> a >> c >> b;
        if (c == '=')
            uni(a, b);
        else
            op.push_back({ a,b,c });
    }

    int cnt = 0;
    for (int i = 0; i < n; i++)
        if (anc(i) == i)
        {
            //cout << i << endl;
            cnt++;
        }

    for (int i = 0; i < op.size(); i++)
    {
        int a = op[i].a, b = op[i].b;
        char c = op[i].c;
        if (anc(a) == anc(b))
        {
            //cout << 1 << endl;
            cout << "inconsistent";
            return 0;
        }
        if (c == '>')
        {
            add(anc(a), anc(b));
            ru[anc(b)]++;
        }
        else
        {
            add(anc(b), anc(a));
            ru[anc(a)]++;
        }
    }

    queueq;
    int tot = 0;
    for (int i = 0; i < n; i++)
        if (!ru[i] && fa[i] == i)
        {
            q.push(i);
            //cout << i << endl;
            tot++;
        }
    while (!q.empty())
    {
        int from = q.front();
        q.pop();
        for (int i = head[from]; i != -1; i = e[i].next)
        {
            int to = e[i].to;
            ru[to]--;
            if (!ru[to])
            {
                q.push(to);
                tot++;
            }
        }
    }
    //cout << tot << " " << cnt << endl;
    if (tot == cnt)
        cout << "consistent" << endl;
    else cout << "inconsistent" << endl;

    return 0;

}