[CF723E] One-Way Reform - 歐拉回路
阿新 • • 發佈:2020-09-01
Description
給一張無向圖定向,使得有最多的點滿足入度等於出度。\(T \le 200, n \le 200, m\le 20000\)
Solution
建一虛點,將所有奇度點與虛點間連虛邊,構造一條歐拉回路,刪去所有虛邊,即得
(因為度數忘記清零 WA 了若干發)
#include <bits/stdc++.h> using namespace std; #define int long long const int N = 405; const int dbg = 0; #define MAXN N namespace euler { stack<int> S; int edge[MAXN][MAXN]; int n,m,vis[N]; vector<pair<int,int>> ans; void reset() { memset(edge,0,sizeof edge); memset(vis,0,sizeof vis); } void dfs(int x) { vis[x]=1; S.push(x); for(int i=1; i<=n; i++) { if(edge[x][i]>0) { edge[i][x]=edge[x][i]=0; ans.push_back({x,i}); dfs(i); break; } } } void fleury(int x) { S.push(x); while(!S.empty()) { int b=0; for(int i=1; i<=n; i++) { if(edge[S.top()][i]>0) { b=1; break; } } if(b==0) { S.pop(); } else { int y=S.top(); S.pop(); dfs(y); } } } void make(int p,int q) { edge[p][q]++; edge[q][p]++; } } int d[N],edge[N][N]; void solve() { int n,m; euler::reset(); memset(edge,0,sizeof edge); memset(d,0,sizeof d); cin>>n>>m; int t1,t2,tot=0; for(int i=1;i<=m;i++) { cin>>t1>>t2; euler::make(t1,t2); euler::make(t2,t1); edge[t1][t2]=1; edge[t2][t1]=1; d[t1]++; d[t2]++; } for(int i=1;i<=n;i++) { if(d[i]&1) { euler::make(n+1,i); } else { ++tot; } } cout<<tot<<endl; euler::n=n+1; for(int i=1;i<=n+1;i++) { if(euler::vis[i]==0) { euler::fleury(i); } } for(auto i:euler::ans) { if(i.first==n+1 || i.second==n+1) continue; cout<<i.first<<" "<<i.second<<endl; } euler::ans.clear(); } signed main() { int t; cin>>t; while(t--) { solve(); } }