zoukankan      html  css  js  c++  java
  • CodeForces-528C Data Center Drama

    题目链接:CodeForces-528C Data Center Drama

    题意

    给出一个无向图(连通,可能有重边和自环),要求加尽量少的边,并给每条边定向,使每个结点的入度和出度都是偶数。


    思路

    对于度数为奇数的结点,加边依次连接,例如结点$1,2,3,4$的度数为奇数,则连接$(1,2)$,$(3, 4)$,使所有结点度数都为偶数,则为欧拉图。

    如果此时边数为奇数,则对任一结点加个自环,这样可以构造出偶数长度的欧拉回路。沿着欧拉回路每隔一条边反向一次,可令结点每一条入边和出边变成两条入边或两条出边,就满足了题目要求的每个结点的入度和出度都是偶数。

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


    代码实现

    #include <cstdio>
    #include <cstring>
    const int N = 100010, M = 500010;
    struct Edge
    {
        int to, nex;
    } edge[M];
    int cnt_e, tot;
    int head[N], deg[N], ans[M];
    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) {  // 求欧拉回路方案,存在ans中
        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;
                dfs(v);
            }
        }
        ans[tot++] = u; // 要后序回溯时记录路径,不能前序记录
    }
    
    int main() {
        int n, m;
        while (~scanf("%d %d", &n, &m)) {
            init();
            int ans1 = 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]++;
            }
            int pre;
            tot = 0;
            for (int i = 1; i <= n; i++) {
                if (deg[i] & 1) {
                    if (tot & 1) {
                        add_edge(pre, i);
                        add_edge(i, pre);
                        ans1++;
                    }
                    else pre = i;
                    tot++;
                }
            }
            if (ans1 & 1) {
                ans1++;
                add_edge(1, 1);
            }
            printf("%d
    ", ans1);
            tot = 0;
            dfs(1);
            for (int i = 0; i < tot - 1; i++) {
                if (i & 1) printf("%d %d
    ", ans[i], ans[i+1]);
                else printf("%d %d
    ", ans[i+1], ans[i]);
            }
            if (!(tot & 1)) puts("1 1");
        }
        return 0;
    }
    View Code
    作者:_kangkang
    本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    PHP语言参考类型/变量/常量/表达式/运算符/控制结构/函数
    代码的可维护性问题
    null与DBNull转换到String型
    Sqlserver数据库表空间统计
    MS SqlServer中少用但是好用的SQL语句[原创]
    数据库安装没装好,害死人啊
    PHP语言参数类与对象
    PHP,MySQL的安装与配置
    PHP特性
    在NebBean中配置常用插件调试/预览页面/打开项目文件夹/JS代码提示
  • 原文地址:https://www.cnblogs.com/kangkang-/p/11380634.html
Copyright © 2011-2022 走看看