题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6109
题意:中文题面
解法:每次都贪心地尝试将尽量多的条件放进当前这组,遇到第一个与已有条件冲突时,就是分割的时候。相等具有传递性,直接用并查集维护,不相等的关系用set维护,注意到x1=x2,x1!=x3,x2!=x4,那么有x1!=x4,x2!=x3,所以用并查集合并(x1,x2)的时候,就需要把x1的不等信息合并到x2上。
#include <bits/stdc++.h> using namespace std; const int maxn = 1e5+10; namespace DSU{ int fa[maxn]; int find_set(int x){ if(x==fa[x]) return x; else return fa[x]=find_set(fa[x]); } }; using namespace DSU; int n; set <int> S[maxn]; void init(){ for(int i=1; i<=n; i++){ S[i].clear(); fa[i]=i; } } int a[maxn], b[maxn], c[maxn]; int ans[maxn]; int main() { while(~scanf("%d", &n)) { init(); for(int i=1; i<=n; i++){ scanf("%d %d %d", &a[i],&b[i],&c[i]); } int cnt = 0; for(int i=1; i<=n; i++){ int u = find_set(a[i]); int v = find_set(b[i]); if(c[i] == 1){ if(u==v) continue; else if(S[u].find(v)!=S[u].end()){ ans[++cnt] = i; init(); }else{ for(set<int>::iterator it=S[v].begin(); it!=S[v].end(); it++){ S[u].insert(*it); S[*it].erase(v); S[*it].insert(u); } S[v].clear(); fa[v] = u; } } else{ if(u==v){ ans[++cnt]=i; init(); }else{ S[u].insert(v); S[v].insert(u); } } } printf("%d ", cnt); for(int i=1; i<=cnt; i++){ printf("%d ", ans[i]-ans[i-1]); } } return 0; }