首页 > 代码库 > HDU 1811
HDU 1811
http://acm.hdu.edu.cn/showproblem.php?pid=1811
中文码题
对于等号的情况,用并查集合并(因为编号不同一定可以分出先后)
然后判断能否构成拓扑排序,以及拓扑排序是不是唯一的
题不难,考验代码能力,能1A证明手感还不错
#include <iostream>#include <cstdio>#include <cstring>#include <map>#include <algorithm>#include <queue>#include <cmath>#include <stack>#include <set>using namespace std;int vis[10005],head[10005],cnt,fa[10005],st[10005];struct p{ int a,b; char op[5];}kk[10005];struct node{ int s,t,nxt;}e[1000005];void add(int s,int t){ e[cnt].s=s;e[cnt].t=t;e[cnt].nxt=head[s];head[s]=cnt++;}void INIT(){ cnt=0; memset(head,-1,sizeof(head));}int find(int x){ return fa[x]==x?x:fa[x]=find(fa[x]);}int dfs(int u){ vis[u]=-1; for(int i=head[u];i!=-1;i=e[i].nxt){ int v=e[i].t; if(vis[v]<0)return 0; else if(!vis[v] && !dfs(v))return 0; } vis[u]=1; return 1;}int OK(int n){ for(int i=0;i<n;i++){ if(!vis[i] && !st[i] && !dfs(i))return 0; } return 1;}int IN[10005];int main(){ int n,m; while(~scanf("%d%d",&n,&m)){ INIT(); for(int i=0;i<n;i++)fa[i]=i; memset(IN,0,sizeof(IN)); memset(st,0,sizeof(st)); int flag=1; for(int i=0;i<m;i++){ scanf("%d%s%d",&kk[i].a,kk[i].op,&kk[i].b); if(kk[i].op[0]==‘=‘){ int pa=find(kk[i].a); int pb=find(kk[i].b); if(pa!=pb){ fa[pa]=pb; st[pa]=1; } } else{ int pa=find(kk[i].a); int pb=find(kk[i].b); if(pa==pb)flag=0; } } if(!flag)puts("CONFLICT");//所给信息矛盾 else{ for(int i=0;i<m;i++){ if(kk[i].op[0]==‘>‘){ add(find(kk[i].a),find(kk[i].b)); IN[find(kk[i].b)]++; } else if(kk[i].op[0]==‘<‘){ add(find(kk[i].b),find(kk[i].a)); IN[find(kk[i].a)]++; } } memset(vis,0,sizeof(vis)); if(!OK(n))puts("CONFLICT");//有环 else{ queue <int> q; for(int i=0;i<n;i++){ if(!st[i] && !IN[i]) q.push(i); } int flag=1; while(!q.empty()){ if(q.size()>1){ flag=0; break; } int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=e[i].nxt){ int v=e[i].t; IN[v]--; if(!IN[v])q.push(v); } } if(!flag)puts("UNCERTAIN");//拓扑结构一层多于一个点,有多种情况 else puts("OK"); } } } return 0;}
HDU 1811
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。