Rank of Tetris HDU1811 并查集+拓扑排序
题意:有A>B A=B A<B 三种情况,是否能通过多次判断出各自排名
Sample Input
3 3 0 > 1 1 < 2 0 > 2 4 4 1 = 2 1 > 3 2 > 0 0 > 1 3 3 1 > 0 1 > 2 2 < 1
Sample Output
OK CONFLICT UNCERTAIN
#include<iostream> #include<algorithm> #include<string> #include<cmath> #include<cstring> #include<set> #include<map> #include<queue> #include<time.h> #include<cstdio> #include<stack> using namespace std; typedef long long ll; const int maxn = 1000000; const int mod = 1e9+7; #define pb push_back // #define long long int #define INF 0x3f3f3f3f; using namespace std; /* 2020.10.15 */ int pre[maxn]; int mk[maxn]; int n,m; int sum; int a[maxn]; int b[maxn]; char op[maxn]; vector<int> nex[maxn]; int find(int x) { if(x!=pre[x]) pre[x] = find(pre[x]); return pre[x]; } void init() { for(int i=0;i<n;i++) { pre[i] = i; mk[i] = 0; nex[i].clear(); } } bool uoin(int x,int y) { int u = find(x); int v = find(y); if(u==v) return true; pre[u] = v; return false; } void topsort() { queue<int> q; bool flag = 0; for(int i=0;i<n;i++) if( mk[i] == 0 && pre[i] == i) q.push(i); while(!q.empty()) { if(q.size()>1) flag = 1; int cur = q.front(); q.pop(); sum--; for(int i=0;i<nex[cur].size();i++) { if(--mk[nex[cur][i]]==0) { q.push(nex[cur][i]); } } } if( sum>0 ) printf("CONFLICT\n"); else if(flag) printf("UNCERTAIN\n"); else printf("OK\n"); } int main() { while(scanf("%d %d",&n,&m)!=EOF) { init(); sum = n; for(int i=0;i<m;i++) { scanf("%d %c %d",&a[i],&op[i],&b[i]); if(op[i]=='=') { if(!uoin(a[i],b[i])) { sum--; } } } for(int i=0;i<m;i++) { if(op[i]=='=')continue; int u = find(a[i]); int v = find(b[i]); if(op[i]=='>') { nex[u].pb(v); mk[v]++; } else { nex[v].pb(u); mk[u]++; } } topsort(); } //system("pause"); }
题解: A=B时候 并查集uoin 拓扑排序总数 - 1 , A>B A<B 情况进行拓扑排序
mk[i] 表示该点入度