Codeforces Round #375 (Div. 2) E. One-Way Reform(有n个点,m条无向边,给每条边定向,使得入度等于出度的点最多)

版权声明:ˋ( ° ▽、° )  ̄へ ̄ https://blog.csdn.net/acm_fighting/article/details/52735249

传送门:Codeforces Round #375 (Div. 2) E. One-Way Reform


题意:
有n个点,m条无向边,给每条边定向,使得入度等于出度的点最多
(n<=200,m<=20000)


思路:
猜想:度数为偶数的都是可以的->欧拉回路证明


#include<bits/stdc++.h>
using namespace std;
const int N=210;
typedef pair<int,int> PI;
struct Edge{
    int from,to,next;
    bool flag;
}e[N*N];
int head[N],tot,degree[N],ed;
vector<int>tmp;
vector<PI>ans;

void init(){
    memset(head,-1,sizeof(head));
    tot=0;
}

void addedge(int from,int to){
    e[tot]=(Edge){from,to,head[from],false};
    head[from]=tot++;
}

void dfs(int u){
    for(int &i=head[u];i!=-1;i=e[i].next){
        if(!e[i].flag){
            e[i].flag=true;
            e[i^1].flag=true;
            if(i<=ed)
                ans.push_back(make_pair(e[i].from,e[i].to));
            dfs(e[i].to);
        }
    }
}

int main(){
    int _,n,m;
    scanf("%d",&_);
    while(_--){
        scanf("%d%d",&n,&m);
        int u,v;
        memset(degree,0,sizeof(degree));
        ans.clear();
        tmp.clear();
        init();
        for(int i=1;i<=m;i++){
            scanf("%d%d",&u,&v);
            addedge(u,v);
            addedge(v,u);
            degree[u]++,degree[v]++;
        }
        int Ans=n;
        for(int i=1;i<=n;i++)
            if(degree[i]&1)
                tmp.push_back(i),Ans--;
        ed=tot-1;
        for(int i=0;i<tmp.size();i+=2)
            addedge(tmp[i],tmp[i+1]),addedge(tmp[i+1],tmp[i]);
        for(int i=0;i<tot;i++)
            if(!e[i].flag)
                dfs(e[i].to);
        printf("%d\n",Ans);
        for(int i=0;i<m;i++)
            printf("%d %d\n",ans[i].first,ans[i].second);
    }
    return 0;
}
展开阅读全文

没有更多推荐了,返回首页