/* https://codeforces.com/problemset/problem/36/E 欧拉路+并查集+思路~ 简直要被绕晕了……有好多细节要注意…… 首先,要分为只有一个联通块,有一个联通块和有两个及以上联通块,判断联通块数用并查集。 最后一种是不行的,直接输出-1。 对于其余两种,要判断每个点的入度是否满足欧拉路条件(没有奇点或有两个奇点),特别的,对于第二种, 每个连通块内要分别判断。 然后,如果有两个奇点,从其中一个出发遍历即可。 在第一种情况中,如果有0个或2个起点,则求出总的欧拉路后从任意处截断。 如果有4个起点,任选两个连边后求欧拉路,再在连的边处截断。 https://blog.csdn.net/xianpingping/article/details/82468730 */ #include #include #include #include #define M 10100 using namespace std; struct abcd { int to, num, next; bool flag; } table[M << 1]; int head[M], tot = 1; int n = 10000, m, a[2], degree[M]; int stack[M], top; void Add(int x, int y, int z) { degree[y]++; table[++tot].to = y; table[tot].num = z; table[tot].next = head[x]; head[x] = tot; } namespace Union_Find_Set { int fa[M], rank[M]; int Find(int x) { if (!fa[x] || fa[x] == x) return fa[x] = x; return fa[x] = Find(fa[x]); } void Union(int x, int y) { x = Find(x); y = Find(y); if (x == y) return; if (rank[x] > rank[y]) swap(x, y); if (rank[x] == rank[y]) rank[y]++; fa[x] = y; } } // namespace Union_Find_Set void DFS(int x) { int i; for (i = head[x]; i; i = head[x]) { head[x] = table[head[x]].next; if (table[i].flag) continue; table[i ^ 1].flag = true; DFS(table[i].to); stack[++top] = table[i].num; } } int main() { #ifndef ONLINE_JUDGE freopen("CF36E.in", "r", stdin); #endif using namespace Union_Find_Set; int i, x, y; cin >> m; if (m == 1) { cout << -1 << endl; return 0; } for (i = 1; i <= m; i++) { scanf("%d%d", &x, &y); Add(x, y, i); Add(y, x, i); Union(x, y); } for (i = 1; i <= n; i++) if (head[i]) { if (!a[0]) a[0] = i; else if (Find(i) != Find(a[0])) { if (!a[1]) a[1] = i; else if (Find(i) != Find(a[1])) return cout << -1 << endl, 0; } } if (a[1]) { int cnt[2] = {0, 0}; int st[2] = {a[0], a[1]}; for (i = 1; i <= n; i++) if (degree[i] & 1) { cnt[Find(i) == Find(a[1])]++; st[Find(i) == Find(a[1])] = i; } if (cnt[0] > 2 || cnt[1] > 2) return cout << -1 << endl, 0; DFS(st[0]); cout << top << endl; while (top) printf("%d%c", stack[top], top == 1 ? '\n' : ' '), top--; DFS(st[1]); cout << top << endl; while (top) printf("%d%c", stack[top], top == 1 ? '\n' : ' '), top--; } else { int st[4] = {0, 0, 0, 0}; for (i = 1; i <= n; i++) if (degree[i] & 1) { if (!st[0]) st[0] = i; else if (!st[1]) st[1] = i; else if (!st[2]) st[2] = i; else if (!st[3]) st[3] = i; else return cout << -1 << endl, 0; } if (!st[0]) { DFS(a[0]); cout << 1 << '\n' << stack[top--] << endl; cout << top << endl; while (top) printf("%d%c", stack[top], top == 1 ? '\n' : ' '), top--; } else if (!st[2]) { DFS(st[0]); cout << 1 << '\n' << stack[top--] << endl; cout << top << endl; while (top) printf("%d%c", stack[top], top == 1 ? '\n' : ' '), top--; } else { Add(st[0], st[1], m + 1); Add(st[1], st[0], m + 1); DFS(st[2]); for (i = 1; i <= top; i++) if (stack[i] == m + 1) break; cout << top - i << endl; while (top > i) printf("%d%c", stack[top], top == i + 1 ? '\n' : ' '), top--; top--; cout << top << endl; while (top) printf("%d%c", stack[top], top == 1 ? '\n' : ' '), top--; } } return 0; }