这个题我提交了差不多40次。其中可能主要的原因是我没有看清楚题吧。在CONFLICT和UNCERTAIN并存的时候输出CONFLICT。我一直都没有考虑这个。加了这个一下就过了。
主要算法:
1、用并查集把有=的合并为一个点
2、拓扑排序,一定要排序到最后,不能发现了 UNCERTAIN就停止
代码:
/* ID: mnlm1991 PROG: hdoj 1811 LANG: C++ */ #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<vector> #include<algorithm> #include<string> #include<map> #include<set> #include<bitset> #include<queue> #include<iostream> using namespace std; const int MaxN = 10001; const int MaxM = 20001; int N; int M; char ANS[][20] = {"OK", "UNCERTAIN", "CONFLICT"}; vector <pair<int, int> > vp; struct Arc { int adj; int next; }arc[MaxM]; struct Node { int indeg; int first; }node[MaxN]; int cnt; int father[MaxN]; int rank[MaxN]; void Init() { int i; for (i = 0; i < N; i++) { node[i].first = i; node[i].indeg = 0; arc[i].next = -1; father[i] = i; rank[i] = 0; } cnt = N; return; } int Find_Set(int x) { if (x != father[x]) { father[x] = Find_Set(father[x]); } return father[x]; } void Union(int x, int y) { x = Find_Set(x); y = Find_Set(y); if (x == y) return; if (rank[x] > rank[y]) { father[y] = x; } else { if (rank[x] == rank[y]) { rank[y]++; } father[x] = y; } } void Insert(int a, int b) { int p = node[a].first; while (arc[p].next != -1) { if (b == arc[p].adj) { break; } p = arc[p].next; } if (arc[p].next == -1) { arc[p].adj = b; arc[cnt].next = -1; arc[p].next = cnt++; node[b].indeg++; } return ; } int vi[MaxN]; int ll; void Erase(int a) { int p = node[a].first; while (arc[p].next != -1) { if (--node[arc[p].adj].indeg == 0) { vi[ll++] = arc[p].adj; } p = arc[p].next; } return ; } int check() { if (ll == 0) { return 2; } else if (ll != 1) { return 1; } else { return 0; } } int TopSort() { int i; ll = 0; int t = 0; for (i = 0; i < N; i++) { if (father[i] == i) { t++; if (node[i].indeg == 0) { vi[ll++] = i; } } } int ret = check(); while (ll-- && --t) { Erase(vi[ll]); ret = max(ret, check()); } return ret; } int GetAns() { vector <pair<int, int> >::iterator it; int a, b; for (it = vp.begin(); it != vp.end(); it++) { a = it -> first; b = it -> second; if (Find_Set(a) != Find_Set(b)) { Insert(Find_Set(a), Find_Set(b)); } else { return 2; } } return TopSort(); } int main() { while (scanf("%d%d", &N, &M) != EOF) { Init(); int cc = 0; vp.clear(); while (M--) { int a, b; char op; scanf("%d %c %d", &a, &op, &b); if (op == '>') { vp.push_back(make_pair(a, b)); } else if (op == '<') { vp.push_back(make_pair(b, a)); } else { Union(a, b); } } printf("%s/n", ANS[GetAns()]); } return 0; } /* 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 3 3 0 = 1 1 = 2 2 > 1 3 3 1 = 0 0 = 2 0 > 2 3 3 0 = 1 1 = 2 0 = 2 10 2 1 > 2 2 > 1 */