题目链接: Rank of Tetris
思路
我们先处理=的情况,把相等关系的两个数字合并,最终只用他们的根来代表他们。然后再处理> < 的情况,我们需要先找到每个数字的根,再进行边的连接。我们还需要记录缩点后最终有几个数字,以及进行topo的时候,放进队列的条件是in[] == 0 && find[i] == i(因为有些数字没有边连接,它们被我们合并了,就是=的情况)
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
int cnt,sum;
vector<int>G[20001];
int flag,n ,f[20001];
int in[20001];
int finder(int x)
{
if(x != f[x])
f[x] = finder(f[x]);
return f[x];
}
void combine(int a,int b)
{
int fa,fb;
fa = finder(a);
fb = finder(b);
if(fa != fb)
{
f[fa] = fb;
}
}
void bfs()
{
int i,u,v;
queue<int>Q;
for(i = 0; i <= n - 1; i++)
if(!in[i] && finder(i) == i)
{
Q.push(i);
}
while(!Q.empty())
{
if(Q.size() >= 2)
flag = 1;
u = Q.front();
Q.pop();
cnt++;
for( i = 0 ; i < G[u].size(); i++ )
{
v = G[u][i];
in[v]--;
if(!in[v])
{
Q.push(v);
}
}
}
if(cnt != sum)
flag = 2;
}
int main()
{
int m,A,B,a[20001],b[20001];
char c[20001];
while(cin >> n >> m)
{
for(int i = 0; i <= n - 1; i++)
G[i].clear();
for(int i = 0 ; i <= n - 1; i++)
f[i] = i;
memset(in,0,sizeof(in));
flag = 0;
cnt = 0;
sum = n;
for(int i = 1; i <= m ; i++)
{
cin >> a[i] >> c[i] >> b[i];
if(c[i] == '=')
{
if(finder(a[i]) != finder(b[i]))
{
combine(a[i],b[i]);
sum--;
}
}
}
for(int i = 1; i <= m ; i++)
{
if(c[i] != '=')
{
int fx = finder(a[i]);
int fy = finder(b[i]);
if(c[i] == '>')
{
G[fx].push_back(fy);
in[fy]++;
}
else
{
G[fy].push_back(fx);
in[fx]++;
}
}
}
bfs();
if(flag == 2)
cout << "CONFLICT" << endl;
else if(flag == 1)
cout << "UNCERTAIN" << endl;
else
cout << "OK" << endl;
}
}