题目链接
题意:给出n个点,m个关系。判断是否能确定独一无二的先后顺序。
先用并查集把相等的点合并成一个点。然后用拓扑排序判断是否有环,是否同时出现多个入度为0的点。
#include <iostream> #include<cstdio> #include<cstring> #include<cmath> #define N 11000 #define M 22000 using namespace std; struct node { int to,next; }e[M]; int n,m,nn,cnt,head[N],in[N],pre[N],a[N],b[N]; char c[N]; void init() { memset(head,-1,sizeof(head)); memset(in,0,sizeof(in)); for(int i=0;i<n;i++) pre[i]=i; cnt=nn=0; } void add_edge(int u,int v) { e[cnt].to=v; e[cnt].next=head[u]; head[u]=cnt++; in[v]++; } int findset(int v) { int t1,t2=v; while(v!=pre[v]) v=pre[v]; while(pre[t2]!=v) { t1=pre[t2]; pre[t2]=v; t2=t1; } return v; } void unions(int u,int v) { int t1=findset(u); int t2=findset(v); if(t1!=t2) pre[t1]=t2; } void toposort() { int k=0,flag1=0,flag2=0; while(k<nn) { int flag=0; for(int i=0;i<n;i++) if(pre[i]==i&&in[i]==0) flag++; if(flag>1) flag1=1; if(!flag) { flag2=1; break; } for(int i=0;i<n;i++) { int t=pre[i]; if(in[t]==0) { in[t]--; k++; for(int j=head[t];j+1;j=e[j].next) { int u=pre[e[j].to]; in[u]--; } break; } } } if(flag2) cout<<"CONFLICT"<<endl; else if(flag1) cout<<"UNCERTAIN"<<endl; else cout<<"OK"<<endl; } int main() { while(~scanf("%d%d",&n,&m)) { init(); for(int i=0;i<m;i++) { scanf("%d %c %d",&a[i],&c[i],&b[i]); if(c[i]=='=') unions(a[i],b[i]); } for(int i=0;i<n;i++) { findset(i); if(pre[i]==i) nn++; } for(int i=0;i<m;i++) { if(c[i]=='>') add_edge(pre[a[i]],pre[b[i]]); if(c[i]=='<') add_edge(pre[b[i]],pre[a[i]]); } toposort(); } }