标签:style blog color os io for ar div log
这道题是拓扑排序和并查集的综合运用。
由于排行榜是一种从高到低的排序。所以在拓扑排序的时候,如果有一次加入的入度为零的点数大于1,就有变得不确定了(UNCERTAIN)。
由于只有一棵树,当树的数量大于1,就矛盾。还有一种产生矛盾的可能是,当输入的是a>b(或者a<b)时,但是并查集中他们的父节点相同。因为这题的一个集合其实被当成了一个点。这样不相等的相等就是矛盾的。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 10010, M =20010; struct node { int to, next; }; node edge[M]; int ind[N], head[N],que[N],f[N],L[N],R[N]; int iq,tot,num,FLAG; char ch[N]; int Find(int x) { if(x==f[x]) return x; return f[x]=Find(f[x]); } void topo(int n) { int i,k,j=0,s; for(i=0;i<n;i++) if(ind[i]==0&&i==Find(i)) que[j++]=i; FLAG=0; if(j>1) FLAG=1; s=j; for(i=0;i<j;i++) { if(j-s>1) FLAG=1; s=j; int u=que[i]; num--; for(k=head[u]; k!=-1; k=edge[k].next) { ind[edge[k].to]--; if(ind[edge[k].to]==0) que[j++]=edge[k].to; } } iq=j; } void addedge(int i,int j) { edge[tot].to=j;edge[tot].next=head[i];head[i]=tot++; } void Link(int i,int j) { int a=Find(i),b=Find(j); if(a!=b) {f[b]=a;} } void init() { tot=0; for(int i=0;i<N;i++) { f[i]=i; head[i]=-1; ind[i]=0; } } int main() { //freopen("test.txt","r",stdin); int n,m,i,j,k; while(scanf("%d%d",&n,&m)!=EOF) { init(); int flag=1; num=n; for(i=0;i<m;i++) { scanf("%d %c %d",&L[i],&ch[i],&R[i]); if(ch[i]==‘=‘) {Link(L[i],R[i]);num--;} } for(i=0;i<m;i++) { if(ch[i]==‘=‘) continue; int a=Find(L[i]),b=Find(R[i]); if(a==b) flag=0; if(ch[i]==‘>‘) {addedge(a,b); ind[b]++;} else {addedge(b,a); ind[a]++;} } topo(n); if(num>1||!flag) printf("CONFLICT\n"); else if(FLAG) printf("UNCERTAIN\n"); else printf("OK\n"); } return 0; }
标签:style blog color os io for ar div log
原文地址:http://www.cnblogs.com/Potato-lover/p/3930147.html