拓扑排序判断环
hdoj 1811 Rank of Tetris
由于有等号的情况,所以要运用并查集,具有相等的点都有公共的父节点,从而相等的化作一个点。
然后拓扑排序判断有没有环。
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
struct Node {
int a, b;
}ns[20005];
int bc[10005];
int N, M, cnt;
int in[10005];
vector<int> vec[10005];
int find(int x) { return bc[x] == x ? x : find(bc[x]) ; }
void merge(int a, int b) {
a = find(a); b = find(b);
a > b ? bc[a] = b : bc[b] = a;
}
void init() {
int i, a, b, finda, findb;
char str[5];
cnt = 0;
for(i=0; i<=10000; ++i) {
bc[i] = i;
in[i] = 0;
vec[i].clear();
}
for(i=0; i<M; ++i) {
scanf("%d %s %d", &a, str, &b);
switch(str[0]) {
case '=' : merge(a, b); break;
case '>' : ns[cnt].a = a; ns[cnt++].b = b; break;
case '<' : ns[cnt].a = b; ns[cnt++].b = a; break;
}
}
for(i=0; i<cnt; ++i) {
finda = find(ns[i].a);
findb = find(ns[i].b);
in[findb] ++;
vec[finda].push_back(findb);
}
}
int solve() {
int i, j, finda, findb;
int ans = 0, count = 0, c = 0;
queue<int> Q;
for(i=0; i<N; ++i) {
if(bc[i]!= i) continue;
count ++;
if(in[i] == 0) Q.push(i);
}
while(Q.size()) {
if(Q.size() > 1) ans = 1;
finda = Q.front();
Q.pop();
c ++;
for(i=0; i<vec[finda].size(); ++i) {
findb = vec[finda][i];
in[findb] --;
if(in[findb] == 0) Q.push(findb);
}
}
if(c < count) ans = -1; //表面有环
return ans;
}
int main() {
// freopen("c:/aaa.txt", "r", stdin);
while(scanf("%d %d", &N, &M) == 2) {
init();
switch(solve()) {
case -1:puts("CONFLICT");break;
case 1:puts("UNCERTAIN");break;
case 0:puts("OK");
}
}
return 0;
}
浙公网安备 33010602011771号