cf 723e One-Way Reform

題意:給你一個無向圖,使其變爲有向,讓入度==出度的點最多。
思路:
想通一個點:只有度數爲偶數的點可以滿足條件。想通這一點之後可以跟奇點建立一些虛邊,跑歐拉回路。
代碼:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define forn(i,n) for(int i=0;i<n;i++)
#define for1(i,n) for(int i=1;i<=n;i++)
#define IO ios::sync_with_stdio(false);cin.tie(0)
const int maxn = 205;
const int maxm = maxn*maxn;

int head[maxn],tot,deg[maxn];
struct edge{
    int v,nex;
    bool ok;
}e[maxm];
vector<pair<int,int> > res;
void init(int n){
    forn(i,n+5) head[i] = -1,deg[i] = 0;
    tot = 0;
    res.clear();
}
void add(int u,int v){
    e[tot] = {v,head[u],0};
    head[u] = tot++;
}
void euler(int u){
    for(int i = head[u];i!=-1;i = e[i].nex){
        if(e[i].ok) continue;
        int v = e[i].v;
        e[i].ok = e[i^1].ok = 1;
        euler(v);
        res.push_back({u,v});
    }
}
int main(){
    IO;
    int t;cin>>t;
    while(t--){
        int n,m;cin>>n>>m;
        init(n);
        forn(i,m){
            int u,v;cin>>u>>v;
            add(u,v),add(v,u);
            deg[u]++,deg[v]++;
        }
        int ans = n;
        for1(i,n) if(deg[i]&1) add(0,i),add(i,0),ans--;
        for1(i,n) if(head[i]!=-1) euler(i);
        cout<< ans <<'\n';
        reverse(res.begin(),res.end());
        for(auto &x:res){
            if(!x.first||!x.second) continue;
            cout<<x.first<<' '<<x.second<<'\n';
        }
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章