一句话题解:
先把相等的点缩小成一个点(并入一个集合),然后在通过大小关系处理剩余点(集合)之间的关系(拓扑排序)
#include<bits/stdc++.h>
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;
};
vector<dx>op;
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)]++;
}
}
queue<int>q;
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;
}