HDU 1811 拓扑排序 并查集
有n个成绩,给出m个分数间的相对大小关系,问是否合法,矛盾,不完全,其中即矛盾即不完全输出矛盾的。
相对大小的关系可以看成是一个指向的条件,如此一来很容易想到拓扑模型进行拓扑排序,每次检查当前入度为0的点个数是否大于1,如大于1则不完全;最终状态检查是否所有点都具有大小关系,遍历过说明有入度。但是由于“=”的存在,要考虑将指向相等数的边全部移到一个数上,故使用并查集预先将相等的点连成块,再进行拓扑排序就行了。
/** @Date : 2017-09-22 13:58:31 * @FileName: HDU 1811 拓扑排序 并查集.cpp * @Platform: Windows * @Author : Lweleth (SoungEarlf@gmail.com) * @Link : https://github.com/ * @Version : $Id$ */ #include <bits/stdc++.h> #define LL long long #define PII pair<int ,int> #define MP(x, y) make_pair((x),(y)) #define fi first #define se second #define PB(x) push_back((x)) #define MMG(x) memset((x), -1,sizeof(x)) #define MMF(x) memset((x),0,sizeof(x)) #define MMI(x) memset((x), INF, sizeof(x)) using namespace std; const int INF = 0x3f3f3f3f; const int N = 2e4+20; const double eps = 1e-8; int fa[N]; int u[N], v[N],p[N]; int deg[N]; vector<int>edg[N]; int sum = 0; int find(int x) { if(x != fa[x]) fa[x] = find(fa[x]); return fa[x]; } int join(int x, int y) { int a = find(x); int b = find(y); if(a != b) { fa[b] = a; sum--; return 1; } return 0; } int top(int n) { //priority_queue<int, vector<int>, greater<int> >q; queue<int>q; for(int i = 0; i < n; i++) if(deg[i] == 0 && i == fa[i]) q.push(i); int flag = 0; while(!q.empty()) { if(q.size() > 1) flag = 1; int nw = q.front(); q.pop(); sum--; for(auto i : edg[nw]) { deg[i]--; if(deg[i] == 0) q.push(i); } } if(sum > 0)//conflict return -1; /*for(int i = 0; i < n; i++) if(deg[i] > 0) return -1;*/ if(flag)//uncertain return 0; return 1; } int main() { int n, m; while(~scanf("%d%d", &n, &m)) { MMF(deg); MMF(p); sum = n; for(int i = 0; i <= n; i++) fa[i] = i, edg[i].clear(); for(int i = 0; i < m; i++) { char t[2]; scanf("%d %s %d", u + i, t, v + i); if(t[0] == '>') p[i] = 1; else if(t[0] == '<') p[i] = -1; else join(u[i], v[i]); } for(int i = 0; i < m; i++)//并掉相等的方便处理 { if(p[i] == 1) { int x = find(u[i]); int y = find(v[i]); edg[y].PB(x); deg[x]++; } else if(p[i] == -1) { int x = find(u[i]); int y = find(v[i]); edg[x].PB(y); deg[y]++; } } int ans = top(n); if(ans == 1) printf("OK\n"); else if(ans == -1) printf("CONFLICT\n"); else printf("UNCERTAIN\n"); } return 0; }