【并查集+拓扑排序】HDU1811 Rank of Tetris
若 a与b的关系为等号则关系已经确定,所以a和b可以看成一个人
接下来用拓扑排序验证是否为唯一/完整的序列
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <string> #include <iostream> #include <algorithm> using namespace std; #include <queue> #include <stack> #include <vector> #include <deque> #include <set> #include <map> #define IN freopen ("in.txt" , "r" , stdin); #define OUT freopen ("out.txt" , "w" , stdout); typedef long long LL; const int MAXN = 10050;//点数的最大值 const int MAXM = 20006;//边数的最大值 const LL INF = 1152921504; const int mod=1000000007; int n,m; int a[MAXM],b[MAXM],fa[MAXN],du[MAXN],sum; char c[MAXM]; vector<int>edge[MAXN]; void init() { sum=n; for(int i=0; i<n; i++) { edge[i].clear(); fa[i]=i,du[i]=0; } } int find(int x) { if(x!=fa[x]) fa[x]=find(fa[x]); return fa[x]; } void merge(int x,int y) { int fx=find(x),fy=find(y); if(fx!=fy) { fa[fx]=fy; sum--; } } void out() { queue<int>q; while(!q.empty()) q.pop(); for(int i=0; i<n; i++) if(du[i]==0&&fa[i]==i) q.push(i); int flag=0; while(!q.empty()) { int x=q.front(); q.pop(); if(!q.empty()) flag=1; sum--; for(int i=0; i<edge[x].size(); i++) if(--du[edge[x][i]]==0) q.push(edge[x][i]); } if(sum>0) puts("CONFLICT"); else if(flag) puts("UNCERTAIN"); else puts("OK"); } int main() { // IN; while(scanf("%d%d",&n,&m)!=EOF) { init(); for(int i=0; i<m; i++) { scanf("%d %c %d",&a[i],&c[i],&b[i]); if(c[i]=='=') merge(a[i],b[i]); } for(int i=0; i<m; i++) { int dx=find(a[i]),dy=find(b[i]); if(c[i]=='>') { edge[dx].push_back(dy); du[dy]++; } else if(c[i]=='<') { du[dx]++; edge[dy].push_back(dx); } } out(); } return 0; }