对于每个连通块欧拉回路存在的条件
无向图:只存在两个或者零个度数为奇数的点
有向图:每个点的入度等于出度或者至多有两个点入度不等于出度且一个出度比入度多一另一个入度比出度多一
HDU 多校第二场 C.cover
题意:给你一个无向图 问你一笔画最多多少次能把所有边覆盖(走过的边不能走)
并且输出每个一笔画的路径(边的下标)
解:给每一对度数为奇数的点连上一条边使之度数变成偶数 然后跑欧拉回路
欧拉回路是从一个正确的点出发然后暴力dfs遇到走过的边就不要走
/*Huyyt*/ #include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; typedef long long ll; typedef unsigned long long ull; const double eps = 1e-9; const int dir[8][2] = {{0, 1}, {1, 0}, {0, -1}, { -1, 0}, {1, 1}, {1, -1}, { -1, -1}, { -1, 1}}; const int mod = 1e9 + 7, gakki = 5 + 2 + 1 + 19880611 + 1e9; const int MAXN = 1e5 + 5, MAXM = 2e5 + 5, MAXQ = 200010, INF = 1e9; const ll LLINF = (1LL << 50); int to[MAXM << 1], nxt[MAXM << 1], Head[MAXN], tot = 1; int index[MAXM << 1]; bool used[MAXM << 1]; inline void addedge(int u, int v, int x) { if (u == v) { return ; } to[++tot] = v; nxt[tot] = Head[u]; index[tot] = x; used[tot] = false; Head[u] = tot; } inline void read(int &v) { v = 0; char c = 0; int p = 1; while (c < '0' || c > '9') { if (c == '-') { p = -1; } c = getchar(); } while (c >= '0' && c <= '9') { v = (v << 3) + (v << 1) + c - '0'; c = getchar(); } v *= p; } int n, m; int du[100005]; bool visit[100005]; int ans = 0; vector<int> anser[100005]; int cnt = 0; void dfs(int x) { int nowindex; visit[x] = true; for (int v, i = Head[x]; i; i = nxt[i]) { v = to[i]; if (used[i]) { continue; } used[i] = used[i ^ 1] = true; nowindex = index[i]; //cout << x << " to " << v << " index " << nowindex << " i " << i << endl; dfs(v); if (nowindex == 0) { anser[++cnt].clear(); } else { anser[cnt].push_back(-nowindex); } } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); int u, v; while (~scanf("%d %d", &n, &m)) { cnt = 0; tot = 1; for (int i = 1; i <= n; i++) { du[i] = 0; visit[i] = false; Head[i] = 0; } for (int i = 1; i <= m; i++) { read(u), read(v); addedge(u, v, i); addedge(v, u, -i); du[u]++, du[v]++; } int aim = 0; for (int i = 1; i <= n; i++) { if (du[i] & 1) { if (aim) { addedge(aim, i, 0); addedge(i, aim, 0); aim = 0; } else { aim = i; } } } for (int i = 1; i <= n; i++) { if (!visit[i] && (du[i] & 1)) { anser[++cnt].clear(); dfs(i); cnt--; } } for (int i = 1; i <= n; i++) { if (!visit[i] && du[i]) { anser[++cnt].clear(); dfs(i); } } printf("%d ", cnt); for (int i = 1; i <= cnt; i++) { printf("%d ", anser[i].size()); for (int j = 0; j < anser[i].size(); j++) { printf("%d", anser[i][j]); if (j == anser[i].size() - 1) { putchar(' '); } else { putchar(' '); } } } } return 0; }