欧拉回路
最多几笔画完,显然和欧拉回路有关。。
我们可以把所有度数为奇数的点两两配对,最后会形成若干个全是偶数度数的联通块。
显然每个联通块都是欧拉回路。
然后我们dfs这些联通块,跑一次欧拉回路。
用数组模拟的邻接表存图后,首先访问的一定是后加的,我们可以利用这些边来将欧拉回路分段。
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define full(a, b) memset(a, b, sizeof a)
#define FAST_IO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
using namespace std;
typedef long long ll;
inline int lowbit(int x){ return x & (-x); }
inline int read(){
int X = 0, w = 0; char ch = 0;
while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
return w ? -X : X;
}
inline int gcd(int a, int b){ return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b){ return a / gcd(a, b) * b; }
template<typename T>
inline T max(T x, T y, T z){ return max(max(x, y), z); }
template<typename T>
inline T min(T x, T y, T z){ return min(min(x, y), z); }
template<typename A, typename B, typename C>
inline A fpow(A x, B p, C lyd){
A ans = 1;
for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
return ans;
}
const int N = 100005;
int n, m, cnt, head[N], d[N], tot;
bool vis[N], kills[N<<2];
struct Edge { int v, next, id; } edge[N<<2];
vector<int> p[N];
void build(){
full(head, -1), full(d, 0);
full(vis, false), full(kills, false);
tot = cnt = 0;
//for(int i = 1; i <= n; i ++) p[i].clear();
}
void addEdge(int a, int b, int id){
edge[cnt].v = b, edge[cnt].id = id, edge[cnt].next = head[a], head[a] = cnt ++;
}
void dfs(int s){
vis[s] = true;
for(int i = head[s]; i != -1; i = edge[i].next){
int u = edge[i].v;
if(kills[i]) continue;
kills[i] = kills[i^1] = true;
dfs(u);
if(edge[i].id) p[tot].push_back(-edge[i].id);
else tot ++;
}
}
int main(){
FAST_IO;
while(cin >> n >> m){
build();
for(int i = 1; i <= m; i ++){
int u, v;
cin >> u >> v;
addEdge(u, v, i), addEdge(v, u, -i);
d[u] ++, d[v] ++;
}
int t = 0;
for(int i = 1; i <= n; i ++){
if(t == 0 && (d[i] & 1)) t = i;
else if(t && (d[i] & 1)){
addEdge(t, i, 0), addEdge(i, t, 0);
t = 0;
}
}
for(int i = 1; i <= n; i ++){
if((d[i] & 1) && !vis[i]){
tot ++, dfs(i), tot --;
}
}
for(int i = 1; i <= n; i ++){
if(!vis[i] && d[i]) tot ++, dfs(i);
}
cout << tot << endl;
for(int i = 1; i <= tot; i ++){
cout << p[i].size();
for(int j = 0; j < p[i].size(); j ++)
cout << " " << p[i][j];
cout << endl;
p[i].clear();
}
}
return 0;
}