欧拉路径与Hierholzer算法
欧拉路径:如果图G中的一个路径包括每个边恰好一次,则该路径称为欧拉路径(Euler path)。
欧拉回路:如果一个回路是欧拉路径,则称为欧拉回路(Euler circuit)。
具有欧拉回路的图称为欧拉图(简称E图)。具有欧拉路径但不具有欧拉回路的图称为半欧拉图。
存在条件
一、无向图
1 存在欧拉路径的充要条件 : 度数为奇数的点只能有0或2个
2 存在欧拉回路的充要条件 : 度数为奇数的点只能有0个
二、有向图
1 存在欧拉路径的充要条件 : 要么所有点的出度均=入度;
要么除了两个点之外,其余所有点的出度=入度 剩余的两个点:一个满足出度-入度=1(起点) 一个满足入度-出度=1(终点)
2 存在欧拉回路的充要条件 : 所有点的出度均等于入度
证明:
我们要使每个边恰好经过一次,那么对于每个中间点,必然从一条入边到达这个点再从一条出边离开这个点那么入边数必然等与出边数,换句话说只要到达一个点必然要有一条边离开这个点。
1.当奇数点个数大于2时,必然有不能完全遍历每一条边。
2.当奇数点为0个时,说明每个点都能成功到达并离开,那此图就构成了欧拉回路,我们必然可以从一个点出发最后再回到这个点。
Hierholzer算法
我们记录每个点的度数,以便于找到起点和终点,当奇数点为2时,选择其中一个点作为起点,另一个点为终点,当奇数点为0时,随机找一个点作为起点,此时图构成欧拉回路,当奇数点不为0或2时,欧拉路不存在。
我们使用DFS遍历每一条边,每走过一条边,就将他删去,保证每条边只经过一次。
我们使用栈来存储路径,以便于最后倒序输出。
#include<bits/stdc++.h>
using namespace std;
const int N=550;
int n;
int g[N][N];
int deg[N];
int odd[N];
int even[N];
int cnt;
stack<int>st;
int maxn;
void Hierholzer(int x)
{
for(int i=1;i<=maxn;i++)
{
if(g[x][i])
{
g[x][i]--;
g[i][x]--;
Hierholzer(i);
}
}
st.push(x);
}
int main(){
cin>>n;
int c=550;
for(int i=1;i<=n;i++)
{
int x,y;
cin>>x>>y;
g[x][y]++;
g[y][x]++;
c=min(c,x);
c=min(c,y);
deg[x]++;
deg[y]++;
maxn=max(maxn,max(x,y));
}
for(int i=1;i<=maxn;i++)
{
if(deg[i]&1) odd[++cnt]=i;
}
if(cnt!=2&&cnt)
{
printf("No solution!");
return 0;
}
int start;
if(cnt) start=min(odd[1],odd[2]);
else start=c;
Hierholzer(start);
while(st.size())
{
printf("%d\n",st.top());
st.pop();
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App