acm.hdu.edu.cn/showproblem.php?pid=1811
看了题之后觉得等于这种关系无法建边,但是觉得这个题实在是像拓扑排序的调调,终于发现可以把等号这种关系的点化成一个点考虑,这就使用到并查集。
AC代码:
#include <queue>
#include <vector>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAX = 10010;
int n,m,cnt,l[MAX<<1],r[MAX<<1];
int father[MAX],into[MAX];
char c[MAX<<1];
vector <int> vt[MAX];
void Init(){
cnt = 0;
for(int i=0; i<=n; i++){
father[i] = i;
vt[i].clear();
into[i] = 0;
}
}
int Find(int x){
if(x != father[x])
father[x] = Find(father[x]);
return father[x];
}
void toposort(){
queue <int> Q;
bool C = false, U = false;
for(int i=0; i<n; i++)
if(!into[i] && Find(i) == i)
Q.push(i);
while(!Q.empty()){
if(Q.size() >= 2) U = true;
int u = Q.front();
Q.pop();
cnt++;
for(int i=0; i<vt[u].size(); i++){
int v = vt[u][i];
if(into[v] > 0) into[v]--;
if(!into[v]) Q.push(v);
}
}
if(cnt < n) C = true;
if(C) puts("CONFLICT");
else if(U) puts("UNCERTAIN");
else puts("OK");
return;
}
int main(){
while(scanf("%d%d",&n,&m) == 2){
Init();
for(int i=0; i<m; i++){
scanf("%d %c %d",&l[i],&c[i],&r[i]);
if(c[i] == '='){
int u = Find(l[i]);
int v = Find(r[i]);
if(u != v){
father[v] = u;
cnt++;
}
}
}
for(int i=0; i<m; i++){
if(c[i] == '=') continue;
int u = Find(l[i]);
int v = Find(r[i]);
if(c[i] == '>'){
if(find(vt[u].begin(),vt[u].end(), v) == vt[u].end()){
vt[u].push_back(v);
into[v]++;
}
}
else{
if(find(vt[v].begin(),vt[v].end(), u) == vt[v].end()){
vt[v].push_back(u);
into[u]++;
}
}
}
toposort();
}
return 0;
}