首先用并查集将“=”的元素合并成一个,然后用拓扑排序判断能否排序
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
int fa[11000];
int N, M, cnt;
vector<int> vec[11000];
int in[11000];
int num1[21000], num2[21000];
char s[21000][3];
int finds( int x ){
int temp = x;
while( temp != fa[temp] ){
temp = fa[temp];
}
while( x != temp ){
int t = fa[x];
fa[x] = temp;
x = t;
}
return temp;
}
int links( int a, int b ){
int f1 = finds( a );
int f2 = finds( b );
if( f1 != f2 ){
fa[f1] = f2;
return 1;
}
return 0;
}
void solve(){
queue<int> q;
while( !q.empty() ){
q.pop();
}
for( int i = 0; i < N; i++ ){
int t = finds( i );
if( in[t] == 0 && fa[t] == i ){
q.push( t );
}
}
bool flag = false;
while( !q.empty() ){
if( q.size() != 1 ){
flag = true;
}
int n = q.front();
q.pop();
cnt--;
for( int i = 0; i < vec[n].size(); i++ ){
in[vec[n][i]]--;
if( in[vec[n][i]] == 0 ){
q.push( vec[n][i] );
}
}
}
if( cnt > 0 ){
printf( "CONFLICT\n" );
}else if( flag ){
printf( "UNCERTAIN\n" );
}else{
printf( "OK\n" );
}
}
int main(){
while( scanf( "%d%d", &N, &M ) != EOF ){
cnt = N;
for( int i = 0; i <= N; i++ ){
vec[i].clear();
fa[i] = i;
}
memset( in, 0, sizeof( in ) );
bool flag = false;
for( int i = 0; i < M; i++ ){
scanf( "%d%s%d", &num1[i], s[i], &num2[i] );
if( s[i][0] == '=' ){
if( links( num1[i], num2[i] ) ){
cnt--;
}
}
}
for( int i = 0; i < M; i++ ){
int f1 = finds( num1[i] );
int f2 = finds( num2[i] );
if( s[i][0] == '>' ){
if( f1 == f2 ){
flag = true;
}
in[f2]++;
vec[f1].push_back( f2 );
}else if( s[i][0] == '<' ){
if( f1 == f2 ){
flag = true;
}
in[f1]++;
vec[f2].push_back( f1 );
}
}
if( flag ){
printf( "CONFLICT\n" );
continue;
}
solve();
}
return 0;
}
/*
4 3
0 > 1
1 = 2
2 > 3
4 3
0 = 1
1 > 2
2 > 3
2 1
0 = 1
3 3
0 = 1
1 = 2
0 = 1
3 3
0 > 1
1 > 2
2 < 1
*/