orz栋爷教我的这题
http://blog.csdn.net/werkeytom_ftd/article/details/72992793
#include <bits/stdc++.h>
#define N 20050
#define M 1000050
#define INF (1<<29)
using namespace std;
typedef pair<int,int> pii;
int h[N],p[N],cur[N],tmp[N],pmt[N],rec[N],S,T,tp,pt,L[N],R[N],tot,sum,cnt;
int A[M],B[M],o[M],t[N],g[N],ans,ttt;
int dfn[N],low[N],ins[N],gS[N],gT[N],tme,ggg;
stack<int> sta;
int n,m;
pii pr[M];
bool vis[N];
inline int rd() {int r;scanf("%d",&r);return r;}
struct Edge{int a,b,v,n,mark;}e[M], idEdge;
void insert(int a,int b,int v,int m) {
e[++cnt] = (Edge){a,b,v,h[a],m}, h[a] = cnt;
e[++cnt] = (Edge){b,a,0,h[b],m}, h[b] = cnt;
}
vector<int> E[N],V[N];
void link(int a, int b, int x) {
E[a].push_back(b), E[b].push_back(a);
V[a].push_back(x), V[b].push_back(x);
}
void dfs(int u,int x) {
vis[u] = 1;
!x ? tmp[++tp] = u : pmt[++pt] = u;
for (int i=0;i<(int)E[u].size();i++)
if (!vis[ E[u][i] ]) dfs(E[u][i], x^1);
}
bool BFS() {
bool flag = 0;
ttt++;
for (int _=1;_<=tot;_++) p[_] = 0, cur[_] = h[_];
queue<int> q;
t[S] = ttt;
q.push(S);
p[S] = 1;
while (!q.empty()) {
int u = q.front(); q.pop();
if (u == T) flag = 1;
for (int i=h[u];i;i=e[i].n) {
int v = e[i].b, cp = e[i].v;
if (cp > 0 && t[v]<ttt)
t[v] = ttt, p[v] = p[u] + 1, q.push(v);
}
}
return flag;
}
int DFS(int u,int fl) {
if (u == T) return fl;
int g=0, f=fl;
for (int i=cur[u];i;i=e[i].n) {
cur[u] = i;
int v = e[i].b, cp = e[i].v, tmp = 0;
if (p[v] == p[u]+1 && cp>0 && (tmp=DFS(v,min(cp,f))) > 0) {
g += tmp, f -= tmp;
e[i^1].v += tmp, e[i].v -= tmp;
}
if (!f) break;
}
return g;
}
void Tarjan(int u) {
dfn[u] = low[u] = ++tme;
sta.push(u); ins[u] = 1;
for (int i=h[u];i;i=e[i].n) if (e[i].v){
int v = e[i].b;
if (!dfn[v]) {
Tarjan(v);
low[u] = min(low[u], low[v]);
} else {
if (ins[v]) low[u] = min(low[u], dfn[v]);
}
}
if (low[u] == dfn[u]) {
++ggg;
do {
int cur = sta.top(); sta.pop();
ins[cur] = 0;
g[cur] = ggg;
} while (ins[u]);
}
}
void find() {
for (int i=1;i<=tot;i++) gS[i] = gT[i] = 0;
queue<int> q;
q.push(S);
gS[S] = 1;
while (!q.empty()) {
int u = q.front(); q.pop();
for (int i=h[u];i;i=e[i].n) {
int v = e[i].b, cp = e[i].v;
if (cp > 0 && !gS[v])
gS[v] = 1, q.push(v);
}
}
q.push(T);
gT[T] = 1;
while (!q.empty()) {
int u = q.front(); q.pop();
for (int i=h[u];i;i=e[i].n) {
int v = e[i].b, cp = e[i^1].v;
if (cp > 0 && !gT[v])
gT[v] = 1, q.push(v);
}
}
}
int main() {
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
n = rd(), m = rd();
for (int _=1;_<=m;_++) {
A[_] = rd(), B[_] = rd();
link(A[_], B[_], _);
}
for (int _=1;_<=n;_++) if (!vis[_]) {
tp = pt = 0;
dfs(_, 0);
//init
for (int _=1;_<=cnt;_++) e[_] = idEdge;
for (int _=1;_<=tot;_++) h[_] = 0;
tot = 0, cnt = 1, sum = 0;
S = ++tot, T = ++tot;
for (int i=1;i<=tp;i++) L[tmp[i]] = ++tot, insert(S, L[ tmp[i] ], 1, 0), rec[L[tmp[i]]] = cnt-1;
for (int i=1;i<=pt;i++) R[pmt[i]] = ++tot, insert(R[ pmt[i] ], T, 1, 0), rec[R[pmt[i]]] = cnt-1;
for (int i=1;i<=tp;i++) {
for (int j=0;j<(int)E[tmp[i]].size();j++) {
int A = tmp[i], B = E[tmp[i]][j];
insert(L[A], R[B], 1, V[A][j]);
}
}
while (BFS()) sum += DFS(S, INF);
for (int i=1;i<=tot;i++) dfn[i] = low[i] = g[i] = 0;
for (int i=1;i<=tot;i++) if (!dfn[i]) Tarjan(i);
find();
for (int i=2;i<=cnt;i+=2)
if (e[i].mark && e[i^1].v) {
int x = e[i].mark;
o[x] = 1;
if (g[e[i].a] == g[e[i].b]) o[x] = 0;
if (gS[e[i].b]) o[x] = 0;
if (gT[e[i].a]) o[x] = 0;
}
}
for (int _=1;_<=m;_++) ans += o[_];
printf("%d\n",ans);
for (int _=1;_<=m;_++) if (A[_]>B[_]) swap(A[_], B[_]);
int tp = 0;
for (int _=1;_<=m;_++)
o[_] ? pr[++tp] = pii(A[_], B[_]),0 :0;
sort(pr+1,pr+tp+1);
for (int _=1;_<=tp;_++)
printf("%d %d\n",pr[_].first,pr[_].second);
return 0;
}