#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <stack>
#include <queue>
#include <map>
#include <vector>
#include <cstdlib>
#include <set>
using namespace std;
#define LL long long
#define N 520
#define M 400020
#define eps 1e-8
#define MP make_pair
#define Pi acos(-1.0)
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define inf 0x3f3f3f3f
#define ls (i << 1)
#define rs (ls | 1)
#define md ((ll + rr) >> 1)
#define lson ll, md, ls
#define rson md + 1, rr, rs
#define mod 1000000007
struct graph {
int n, match[N];
bool adj[N][N];
void clear(int nn = 0) {
n = nn;
memset(adj, 0, sizeof adj);
}
void add(int u, int v) {
adj[u][v] = adj[v][u] = 1;
}
int gao() {
memset(match, -1, sizeof match);
int ans = 0;
for(int i = 1; i <= n; ++i) {
if(match[i] == -1)
ans += bfs(i);
}
return ans;
}
int q[N], pre[N], base[N];
bool inq[N], inblossom[N];
int bfs(int p) {
memset(pre, -1, sizeof pre);
memset(inq, 0, sizeof inq);
for(int i = 1; i <= n; ++i) base[i] = i;
q[0] = p;
inq[p] = 1;
for(int s = 0, t = 1; s < t; ++s) {
int u = q[s];
for(int v = 1; v <= n; ++v) {
if(adj[u][v] && base[u] != base[v] && v != match[u]) {
if(v == p || (match[v] != -1 && pre[match[v]] != -1)) {
int b = contract(u, v);
for(int i = 1; i <= n; ++i) {
if(inblossom[base[i]]) {
base[i] = b;
if(inq[i] == 0) {
inq[i] = 1;
q[t++] = i;
}
}
}
}
else if(pre[v] == -1) {
pre[v] = u;
if(match[v] == -1) {
aug(v);
return 1;
}
else {
q[t++] = match[v];
inq[match[v]] = 1;
}
}
}
}
}
return 0;
}
void aug(int u) {
while(u != -1) {
int v = pre[u];
int k = match[v];
match[u] = v;
match[v] = u;
u = k;
}
}
void change_blossom(int b, int u) {
while(base[u] != b) {
int v = match[u];
inblossom[base[v]] = inblossom[base[u]] = 1;
u = pre[v];
if(base[u] != b) {
pre[u] = v;
}
}
}
int contract(int u, int v) {
memset(inblossom, 0, sizeof inblossom);
int b = lca(base[u], base[v]);
change_blossom(b, u);
change_blossom(b, v);
if(base[u] != b) {
pre[u] = v;
}
if(base[v] != b)
pre[v] = u;
return b;
}
int lca(int u, int v) {
bool in_path[N];
memset(in_path, 0, sizeof in_path);
while(1) {
in_path[u] = 1;
if(match[u] == -1) break;
u = base[pre[match[u]]];
}
while(!in_path[v]) {
v = base[pre[match[v]]];
}
return v;
}
}g;
int n;
int main() {
scanf("%d", &n);
g.clear(n);
int x, y;
while(scanf("%d%d", &x, &y) != EOF) {
g.add(x, y);
}
bool mark[N];
memset(mark, 0, sizeof mark);
int ans = g.gao();
printf("%d\n", ans * 2);
for(int i = 1; i <= n; ++i) {
if(g.match[i] != -1 && mark[i] == 0 && mark[g.match[i]] == 0) {
printf("%d %d\n", i, g.match[i]);
mark[i] = mark[g.match[i]] = 1;
}
}
return 0;
}
搜索
复制