【题解】CF527E Data Center Drama
我们先考虑什么情况下有解。由于每个点出度和入度都是偶数,所以每个点的度数都是偶数是必要条件。
所有点度数是偶数,说明一定存在一条欧拉回路。不难发现如果欧拉回路长度是偶数,那么我们将奇数边正向,偶数边逆向即为合法构造。即 \(a\to b \leftarrow c \to d \leftarrow a\) 等等。
如果不是偶数,那么至少要添加一条边,我们发现只用添加一个自环 \(a\to a\) 即可满足条件。
#define N 1000005
int n, m, h[N], tot = 1, in[N], v[N], u[N], t;
struct edge{int to, nxt;}e[N];
void add(int x,int y){e[++tot].nxt = h[x], h[x] = tot, e[tot].to = y;}
void dfs(int x){
for(int &i = h[x]; i; i = e[i].nxt)if(!v[i])
v[i] = v[i ^ 1] = 1, dfs(e[i].to);
u[++t] = x;
}
vector<Pr>ed;
int main() {
read(n, m);
rp(i, m){
int x, y; read(x, y);
in[x] ++, in[y] ++;
add(x, y), add(y, x);
}
int lst = 0;
rp(i, n)if(in[i] & 1){
if(lst)add(lst, i), add(i, lst), lst = 0;
else lst = i;
}
rp(i, n){
t = 0, dfs(i);
if(!(t & 1))ed.pb(mp(i, i));
rp(i, t - 1)if(i & 1)ed.pb(mp(u[i], u[i + 1])); else ed.pb(mp(u[i + 1], u[i]));
}
printf("%d\n", si(ed));
go(x, ed)printf("%d %d\n", x.fi, x.se);
return 0;
}