|
|
#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;
|
|
|
} |