zoukankan      html  css  js  c++  java
  • Codeforces 723E欧拉回路

    题意

    给定一张无向图,将每条边变成有向边,使得出度等于入度的点最多。输出最终入度=出度点的个数和每条有向边。

    分析

    第一问统计度数为偶数的点即可。

    联想欧拉回路上的每个点出度=入度,但原图并不一定是无向图的欧拉回路,可以补成欧拉回路,输出的时候不输出补的边。

    考虑到一张图的奇数度数的点有偶数个,把它们分成2个点一组,然后每组加边,那么原图就有欧拉回路了。

    代码

    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <queue>
    #include <map>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #define MAX 207
    #define MAXN 10007
    #define MAXM 50007
    #define MOD 1000000007
    using namespace std;
    typedef long long LL;
    struct Edge{
        int from;
        int to;
        int next;
    }edge[MAXM*2];
    int head[MAXN],tot,n,m,degree[MAXN];
    int ans[MAXM*2],ansi,visit[MAXM*2],flag[MAXM*2];
    void addEdge(int u, int v){
        edge[tot].from=u;
        edge[tot].to=v;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    void init(){
        tot=ansi=0;
        memset(head,-1,sizeof head);
        memset(visit,0,sizeof visit);
        memset(degree,0,sizeof degree);
        memset(flag,0,sizeof flag);
    }
    void dfs(int now){
        for(int k=head[now];k!=-1;k=edge[k].next){
            if(!visit[k]){
                visit[k]=visit[k^1]=1;
                dfs(edge[k].to);
                ans[ansi++]=k^1;
            }
        }
    }
    int cas,u,v;
    int main(){
        scanf("%d",&cas);
        while(cas--){
            scanf("%d%d",&n,&m);
            init();
            for(int i=0;i<m;i++){
                scanf("%d%d",&u,&v);
                degree[u]++;
                degree[v]++;
                addEdge(u,v);
                addEdge(v,u);
            }
            int ans1=0;
            int js[MAXN],jsi=0;
            for(int i=1;i<=n;i++){
                if((degree[i]&1)==0){
                    ans1++;
                }
                else{
                    js[jsi++]=i;
                }
            }
            for(int i=0;i<jsi;i+=2){
                //printf("add:%d %d\n",js[i],js[i+1]);
                addEdge(js[i],js[i+1]);
                addEdge(js[i+1],js[i]);
            }
            printf("%d\n",ans1);
            for(int i=1;i<=n;i++){
                 dfs(i);
            }
            for(int i=0;i<ansi;i++){
                int d=ans[i];
                if(d<m*2) 
                printf("%d %d\n", edge[d].from,edge[d].to);
            }
        }
        
        return 0;
    }
  • 相关阅读:
    Azkaban的架构(三)
    Azkaban的功能特点(二)
    Hadoop工作流不足(六)
    Hadoop工作流--JobControl(五)
    ruby on rails创建的页面訪问很慢
    C#实现树的双亲表示法
    SetCapture ReleaseCapture
    HDU 4923 Room and Moor
    Spring概述
    WinMM.dll 函数汇总
  • 原文地址:https://www.cnblogs.com/shuiming/p/7203608.html
Copyright © 2011-2022 走看看