You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 lines
1.9 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, M = 2e6 + 10;
// 标准错误答案@
// #2162. 「POI2011 R2 Day1」垃圾运输 Garbage
// https://loj.ac/s/1857935
// 并查集
int p[N], sz[N];
int find(int x) {
if (x == p[x]) return x;
return p[x] = find(p[x]);
}
int e[M], h[N], idx, w[M], ne[M];
void add(int a, int b, int c = 0) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
int d[N];
vector<int> res[N];
int rl;
int st[M];
void dfs(int u) {
for (int i = h[u]; ~i; i = h[u]) {
h[u] = ne[i];
if (st[i]) continue;
st[i] = st[i ^ 1] = 1;
int v = e[i];
dfs(v);
cout << u << " ";
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("P3520.in", "r", stdin);
#endif
memset(h, -1, sizeof h);
int n, m;
scanf("%d %d", &n, &m);
// 初始化并查集
for (int i = 1; i <= n; i++) p[i] = i, sz[i] = 1;
int a, b, s, t;
while (m--) {
scanf("%d %d %d %d", &a, &b, &s, &t);
if (s ^ t) {
add(a, b), add(b, a);
d[a]++, d[b]++;
// 并查集
int pa = find(a), pb = find(b);
if (pa != pb) {
p[pb] = pa;
sz[pa] += sz[pb]; // 维护家庭人员数量
}
}
}
for (int i = 1; i <= n; i++)
if (d[i] % 2) {
puts("NIE");
exit(0);
}
// 肯定是存在欧拉回路,现在是几个环呢?可以用并查集提前处理出来
// 从头到尾,看一下有多少个家庭,就是有多少个环
int cnt = 0;
for (int i = 1; i <= n; i++)
if (d[i] && i == p[i]) cnt++;
cout << cnt << endl;
for (int i = 1; i <= n; i++)
if (d[i] && i == p[i]) {
cout << sz[i] << " " << i << " ";
dfs(i);
cout << endl;
}
return 0;
}