题意:中文题。
分析:先用并查集缩下点,然后用拓扑排序判断一些各种情况即可。
代码:
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<bitset>
#include<math.h>
#include<vector>
#include<string>
#include<stdio.h>
#include<cstring>
#include<iostream>
#include<algorithm>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int N=10010;
const int mod=100000000;
const int MOD1=1000000007;
const int MOD2=1000000009;
const double EPS=0.00000001;
typedef long long ll;
const ll MOD=1000000007;
const int INF=1000000010;
const ll MAX=1ll<<55;
const double pi=acos(-1.0);
typedef double db;
typedef unsigned long long ull;
char s[5];
int nn,f[N],x[N],y[N],z[N];
int tot,d[N],u[N],v[N],pre[N];
void add(int a,int b) {
v[tot]=b;pre[tot]=u[a];u[a]=tot++;
}
int find_f(int a) {
return f[a]==a ? a:f[a]=find_f(f[a]);
}
void unio(int a,int b) {
int fa=find_f(a),fb=find_f(b);
if (fa!=fb) f[fb]=fa,nn--;
}
int main()
{
int a,b,i,k,n,m,l,r;
while (scanf("%d%d", &n, &m)!=EOF) {
for (i=0;i<n;i++) f[i]=i;
for (k=0,nn=n,i=1;i<=m;i++) {
scanf("%d%s%d", &a, s, &b);
if (s[0]=='<') { k++;x[k]=a;y[k]=b;z[k]=1; }
else if (s[0]=='>') { k++;x[k]=a;y[k]=b;z[k]=2; }
else unio(a,b);
}
memset(d,0,sizeof(d));
tot=0;memset(u,-1,sizeof(u));
for (i=0;i<n;i++) f[i]=find_f(i);
for (i=1;i<=k;i++)
if (z[i]==1) add(f[y[i]],f[x[i]]),d[f[x[i]]]++;
else add(f[x[i]],f[y[i]]),d[f[y[i]]]++;
k=0;l=1;r=0;
for (i=0;i<n;i++)
if (f[i]==i&&d[i]==0) y[++r]=i,x[r]=1;
for (;l<=r;l++)
for (i=u[y[l]];i!=-1;i=pre[i]) {
d[f[v[i]]]--;
if (d[f[v[i]]]==0) y[++r]=f[v[i]],x[r]=x[l]+1;
}
if (r<nn) printf("CONFLICT\n");
else {
for (k=1,i=1;i<r;i++)
if (x[i]==x[i+1]) { k=0;break ; }
if (!k) printf("UNCERTAIN\n");
else printf("OK\n");
}
}
return 0;
}