题目大意
略
解题思路
对于相等的关系很好维护,关键是对于不想等的关系。如果(x_i)与(x_j)不相等,那么(x_i)所在集合中的所有点都是和(x_j)所在集合中的所有点不相等的。
把不相等的(x_i)与(x_j),所在集合的代表结点建一条边,如果(x_i)所在集合要和其他集合合并,那么在合并的时候指向被合并集合的边都要指向合并的集合,反之,被合并集合指向其他集合的边也要加进合并的集合里头。如果两个合并的集合之间有边,说明关系冲突。
代码
#include<set>
#include<map>
#include<ctime>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<string>
#include<vector>
#include<climits>
#include<cstring>
#include<cstdlib>
#include<sstream>
#include<iostream>
#include<algorithm>
#define endl '
'
#define clr(arr,b) memset(arr, b, sizeof(arr))
#define IOS ios::sync_with_stdio(false)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, int> P;
typedef pair<ll, int> Pll;
const double pi = acos(-1.0);
const double eps = 1e-8;
const ll MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5+10;
const int maxm = 2e6+10;
struct E {
int to, nxt;
} e[maxm]; int h[maxn], tot;
int l, p[maxn], num[maxn];
void add(int u, int v) {
++num[u];
e[++tot] = {v, h[u]}; h[u] = tot;
}
int find(int x) {
return p[x]==x?p[x]:p[x]=find(p[x]);
}
vector<int> ans, tmp;
bool merge(int a, int b) {
if (num[a]>num[b]) swap(a, b);
num[b] += num[a];
p[a] = p[b];
int last = 0;
for (int i = h[a]; i; i=e[i].nxt) {
int v = e[i].to;
if (v==b) return 1;
e[i^1].to = b;
last = i;
}
if (last) {
e[last].nxt = h[b];
h[b] = h[a];
}
return 0;
}
void solve() {
ans.push_back(tmp.size()/2); tot = 1;
for (auto i : tmp) p[i] = i, h[i] = 0, num[i] = 0;
tmp.clear();
}
int main() {
cin >> l; tot = 1;
for (int i = 0; i<=l; ++i) p[i] = i, num[i] = 0, h[i] = 0;
for (int i = 0, a, b, c; i<l; ++i) {
scanf("%d%d%d", &a, &b, &c);
tmp.push_back(a), tmp.push_back(b);
if (c) {
if (find(a)!=find(b) && merge(find(a), find(b))) solve();
}
else {
if (find(a)==find(b)) solve();
else add(find(a), find(b)), add(find(b), find(a));
}
}
cout << ans.size() << endl;
for (auto v : ans) printf("%d
", v);
return 0;
}