CodeForces-528C Data Center Drama
Posted kangkang-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces-528C Data Center Drama相关的知识,希望对你有一定的参考价值。
题目链接:CodeForces-528C Data Center Drama
题意
给出一个无向图(连通,可能有重边和自环),要求加尽量少的边,并给每条边定向,使每个结点的入度和出度都是偶数。
思路
对于度数为奇数的结点,加边依次连接,例如结点$1,2,3,4$的度数为奇数,则连接$(1,2)$,$(3, 4)$,使所有结点度数都为偶数,则为欧拉图。
如果此时边数为奇数,则对任一结点加个自环,这样可以构造出偶数长度的欧拉回路。沿着欧拉回路每隔一条边反向一次,可令结点每一条入边和出边变成两条入边或两条出边,就满足了题目要求的每个结点的入度和出度都是偶数。
代码实现
#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\n", ans1); tot = 0; dfs(1); for (int i = 0; i < tot - 1; i++) if (i & 1) printf("%d %d\n", ans[i], ans[i+1]); else printf("%d %d\n", ans[i+1], ans[i]); if (!(tot & 1)) puts("1 1"); return 0;
以上是关于CodeForces-528C Data Center Drama的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces 528D Fuzzy Search(FFT)
Codeforces 528A Glass Carving STL模拟