• CodeForces-723E One-Way Reform


    题目链接:CodeForces-723E One-Way Reform

    题意

    给出一个无向图,让我们给边定向,使入度等于出度的结点最多。


    思路

    首先入度等于出度的结点其度数肯定是偶数的,那么能否让所给的图中所有度数为偶的结点都满足要求?

    考虑欧拉图,下面是与欧拉图与此题有关的定义和性质:

    通过图中所有边一次且仅一次的回路称为欧拉回路。

    具有欧拉回路的图称为欧拉图。

    一个无向图存在欧拉回路,当且仅当该图所有结点度数都为偶数,且该图是连通图。

    一个有向图存在欧拉回路,当且仅当该图所有结点的入度等于出度,且该图是连通图。

    显然欧拉图中按欧拉回路给每条边定向能令每个结点的入度都等于出度。

    一个图中度数为奇的结点个数一定是偶数,我们新加一个结点$n+1$,所有度数为奇的结点和$n+1$连边,这样新图中所有结点度数为偶,则为欧拉图。(题目给出的图不一定连通,那我们构造出来的可能是多个欧拉图,不影响答案正确性。)

    dfs跑出欧拉回路给每条边定向,输出属于原图的边即可。原图中度数为偶的结点的连边都没有改动,所以这样构造出来的方案能令原图所有度数为偶的结点满足入度等于出度。

    时间复杂度$O(E)$。


    代码实现

    #include <cstdio>
    #include <cstring>
    const int N = 210, M = N * N + N;
    struct Edge
    {
        int to, nex;
    } edge[M];
    int n, cnt_e;
    int head[N], deg[N];
    bool vis[M];
    void add_edge(int u, int v) {
        edge[++cnt_e].to = v;
        edge[cnt_e].nex = head[u];
        head[u] = cnt_e;
    }
    void init() {
        cnt_e = 1;
        memset(head, 0, sizeof(head));
        memset(deg, 0, sizeof(deg));
        memset(vis, 0, sizeof(vis));
    }
    void dfs(int u) {
        for (int i = head[u]; i; i = head[u]) {
            head[u] = edge[i].nex;
            if (!vis[i|1]) {
                vis[i|1] = true;
                int v = edge[i].to;
                if (u != n + 1 && v != n + 1) printf("%d %d
    ", u, v);
                dfs(v);
            }
        }
    }
    
    int main() {
        int t, m;
        scanf("%d", &t);
        while (t--) {
            init();
            scanf("%d %d", &n, &m);
            for (int i = 0, u, v; i < m; i++) {
                scanf("%d %d", &u, &v);
                add_edge(u, v);
                add_edge(v, u);
                deg[u]++, deg[v]++;
            }
            for (int i = 1; i <= n; i++) {
                if (deg[i] & 1) {
                    add_edge(i, n + 1);
                    add_edge(n + 1, i);
                    deg[n+1]++;
                }
            }
            printf("%d
    ", n - deg[n+1]);
            for (int i = 1; i <= n; i++) dfs(i);
        }
        return 0;
    }
    View Code
    作者:_kangkang
    本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    get与post区别
    移动应用专项测试的思路和方法
    一个完整的http请求响应过程
    Linux基础
    浏览器输入url按回车背后经历了哪些?
    三大浏览器(火狐-谷歌-IE浏览器)驱动版本下载
    boost-序列化
    HTTP 2.0
    http首部字段
    与http协作的web服务器
  • 原文地址:https://www.cnblogs.com/kangkang-/p/11377780.html
Copyright © 2020-2023  润新知