hdu 1811 Rank of Tetris 拓扑排序+并查集
2016-04-27 08:25
441 查看
题目链接
题意:给出n个点,m个关系。判断是否能确定独一无二的先后顺序。
先用并查集把相等的点合并成一个点。然后用拓扑排序判断是否有环,是否同时出现多个入度为0的点。
题意:给出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 ,in ,pre ,a ,b ; char c ; 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(); } }
相关文章推荐
- Mac下Android Studio环境搭建
- UITextfield使用集合
- Git的使用记录
- 普通指针转换智能指针转换时的错误
- bzoj 3339: Rmq Problem(线段树)
- linux系统编程概述-系统调用
- cojs 疯狂的粉刷匠 疯狂的斐波那契 题解报告
- Activiti-Explorer 用户名与密码
- Activiti-Explorer 用户名与密码
- gdb 使用介绍
- Linux下使用GCC命令编译代码(1)
- [BZOJ3339]Rmq Problem(离线+线段树)
- 第k大元素
- php在原生代码中如何简单快速的发送email
- Eclipse 安装Groovy插件
- 记录一下游戏的上线
- 人生小结
- Win10一周年更新PC预览版14332修复内容汇总
- Delphi 10.1 Berlin 官方未列之修正
- dtoc