欧拉回路
定义
图中经过所有边恰好一次的路径叫欧拉路径.
如果此路径的起点和终点相同,则称其为一条欧拉回路.
有向图欧拉路径
1. 恰好存在 $\mathrm{1}$ 个点出度比入度多 $\mathrm{1}$ (这个点即为起点 $\mathrm{s}$)
2. 恰好存在 $\mathrm{1}$ 个点入度比出度多 $\mathrm{1}$ (这个点即为终点 $\mathrm{t}$)
3. 其余节点出度 $\mathrm{=}$ 入度
找到起点后对于每个点遍历一个没遍历过的边即可.
开一个 $\mathrm{del[x]}$ 数组表示前 $\mathrm{del[x]}$ 个边已遍历过,然后更新即可.
#include <cstdio>
#include <cstring>
#include <vector>
#include <stack>
#include <algorithm>
#define N 100009
#define ll long long
#define pb push_back
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
vector<int>G[N];
stack<int>se;
int n , m , del[N], deg[N][2];
void dfs(int x) {
for(int i = del[x]; i < G[x].size() ; i = del[x]) {
++ del[x];
dfs(G[x][i]);
}
se.push(x);
}
int main() {
// setIO("input");
scanf("%d%d", &n, &m);
for(int i = 1; i <= m ; ++ i) {
int x, y;
scanf("%d%d", &x, &y);
G[x].pb(y);
deg[x][1]++;
deg[y][0]++;
}
int flag = 0, s1 = 0, s2 = 0, sta = 1;
for(int x = 1; x <= n ; ++ x) {
if(deg[x][0] != deg[x][1])
++ flag;
// printf("%d %d %d\n", x, deg[x][0], deg[x][1]);
if(deg[x][0] - deg[x][1] == 1) s1 = x;
if(deg[x][1] - deg[x][0] == 1) s2 = x;
}
// printf("%d\n", flag);
if((flag == 0) || ((flag == 2) && s1 && s2)) {
// 合法
if(s2) sta = s2;
for(int i = 1; i <= n ; ++ i) sort(G[i].begin(), G[i].end());
dfs(sta);
while(!se.empty()) {
printf("%d ", se.top());
se.pop();
}
}
else {
printf("No");
}
return 0;
}
有向图欧拉回路
1. 所有点出度等于入度
无向图欧拉路径
1. 恰好两个点度数为奇数
2. 其余点度数为偶数
这里面度数为奇数的点就是起点和终点.
和有向图的求法差不多,不过要开一个 $\mathrm{map}$ 记录一条无向边是否被遍历过.
若该边已被定向,则不能继续访问了.
#include <bits/stdc++.h>
#define N 100009
#define ll long long
#define pb push_back
#define mp make_pair
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int m , deg[N], del[N];
stack<int>se;
vector<int>G[N];
map<pair<int, int>, int>vis;
void dfs(int x) {
for(int i = del[x]; i < G[x].size() ; i = del[x]) {
++ del[x];
int v = G[x][i];
if(!vis[mp(x, v)]) continue;
vis[mp(x, v)] -- ;
vis[mp(v, x)] -- ;
dfs(v);
}
se.push(x);
}
int main() {
// setIO("input");
scanf("%d", &m);
int st = N;
for(int i = 1; i <= m ; ++ i) {
int x, y;
scanf("%d%d", &x, &y);
G[x].pb(y);
G[y].pb(x);
++ deg[x], ++ deg[y];
st = min(st, min(x, y));
vis[mp(x, y)] ++ ;
vis[mp(y, x)] ++ ;
}
for(int i = 1; i <= 500; ++ i) {
sort(G[i].begin(), G[i].end());
}
for(int i = 1; i <= 500; ++ i) {
if(deg[i] & 1) {
st = i;
break;
}
}
dfs(st);
while(!se.empty()) {
printf("%d\n", se.top());
se.pop();
}
return 0;
}
无向图欧拉回路
1. 所有点度数为偶数

浙公网安备 33010602011771号