第一次写欧拉回路,实际上只要dfs下去就可以了,反正每条边都是要遍历一遍的……
关键有两个性质:1.一个无向图存在欧拉回路,当且仅当该图所有顶点度数都为偶数,且该图是连通图。2.一个有向图存在欧拉回路,所有顶点的入度等于出度且该图是连通图。
所以我们可以将所有的奇点之间两两连边使得它们成为偶点。此时这张图上必然存在欧拉路径,也就是所有顶点的入度等于出度,我们只需要减去奇点即可。
#include <bits/stdc++.h> using namespace std; #define maxn 1000000 int n, m, tot, cnt; int e[maxn], rec[maxn], degree[maxn]; int read() { int x = 0, k = 1; char c; c = getchar(); while(c < ‘0‘ || c > ‘9‘) { if(c == ‘-‘) k = -1; c = getchar(); } while(c >= ‘0‘ && c <= ‘9‘) x = x * 10 + c - ‘0‘, c = getchar(); return x * k; } struct edge { int cnp, to[maxn], last[maxn], head[maxn], id[maxn], mark[maxn]; edge() { cnp = 2; } void add(int u, int v) { to[cnp] = v, id[cnp] = 1, last[cnp] = head[u], head[u] = cnp ++; to[cnp] = u, id[cnp] = 0, last[cnp] = head[v], head[v] = cnp ++; } }E1; void dfs(int u) { for(int i = E1.head[u]; i; i = E1.last[i]) { if(E1.mark[i]) continue; int v = E1.to[i]; if(E1.id[i]) E1.mark[i] = E1.mark[i ^ 1] = 1; else E1.mark[i] = E1.mark[i ^ 1] = 2; dfs(v); } } int main() { n = read(), m = read(); for(int i = 1; i <= m; i ++) { int x = read(), y = read(); degree[x] ++, degree[y] ++; E1.add(x, y); } for(int i = 1; i <= n; i ++) if(degree[i] & 1) e[++ cnt] = i; int M = E1.cnp; for(int i = 1; i <= cnt; i += 2) { int x = e[i], y = e[i + 1]; E1.add(x, y); } for(int i = 1; i <= n; i ++) dfs(i); printf("%d\n", n - cnt); for(int i = 2; i < M; i += 2) if(E1.mark[i] == 1) putchar(‘0‘); else putchar(‘1‘); return 0; }
原文地址:https://www.cnblogs.com/twilight-sx/p/9649014.html
时间: 2024-11-05 22:41:21