cf527 E Data Center Drama

題意:無向圖,讓你定向每條邊,有必要可以加一些邊,使得圖中每個點的入度和出度%2==0,輸出最小加邊的構造方式。
思路:奇度相連。a-b-c-d-e改爲a->b<-c->d<-e,邊爲奇數任意一個點連一個自環,之後跑歐拉回路。
代碼:

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