欧拉路径
概念
- 欧拉路径:从某一点出发经过一条不间断的路径,这条路径刚好访问整个图的所有遍一次且仅一次。
- 这个图可以是有向图/无向图。
- 一个图可以有多个欧拉路径
- 欧拉回路:起点和终点为同一个点的欧拉路径。
- 一个图可以有多个欧拉回路
- 欧拉图:具有欧拉回路的图
- 半欧拉图:具有欧拉路径但是不具有欧拉回路的图
存在条件
- 所有有向边改为无向边后图是否连通:可以用dfs或并查集来找
- 欧拉图
- 无向图:所有顶点度数都是偶数
- 有向图:图的所有顶点都满足“入度=出度”
- 半欧拉图
- 无向图:有且仅有两个点的度数是奇数,其余的点度数都为偶数
- 有向图:有且仅有一个点“入度=出度+1” 并且 有且仅有一个点“出度=入度+1”,其余的点“入度=出度”
半欧拉图的起点 & 终点
- 无向图:两个度数为奇数的一个 --> 另一个
- 有向图:“出度=入度+1” --> “入度=出度+1”
欧拉路径算法
- 判断给定图是否是欧拉图/半欧拉图(如果没有连通的限制还要判定是否是连通图)
- 确定路径起点
- 欧拉图任意
- 半欧拉图见上
- 答案栈answer存储途径节点
- 对图进行dfs,节点允许重复经过,边不允许。每访问一条边就删掉,然后对这条边另一端的点进行遍历。每一个节点完成遍历且没有相连边时,将这个节点加入answer
- 遍历结束,answer依次弹出,得到的就是欧拉路径/欧拉回路的节点访问顺序
注意点
不管是answer存边还是存点,都要等dfs完了再存,然后倒序输出。
代码
luogu的模版题:【模版】欧拉路径
#include<bits/stdc++.h> #define ll long long using namespace std; const ll inf=0x3f3f3f3f3f3f3f3f; vector<ll> e[100005]; //邻接表存图 ll nxt[100005]; //从i出发下一个要访问的边的序号为nxt[i](以保证每条边只访问一次) ll in[100005],out[100005]; stack<ll> ans; //答案栈 ll n,m; void dfs(ll x); void solve(); void dfs(ll x){ for(ll i=nxt[x];i<e[x].size();i=nxt[x]){ nxt[x]++; dfs(e[x][i]); } ans.push(x); } void solve(){ cin>>n>>m; for(ll i=1,x,y;i<=m;i++){ cin>>x>>y; e[x].push_back(y); ++out[x],++in[y]; } //判断是否有欧拉路径 ll start=0,start_x=1,end=0,end_x=0,cnt=0; for(ll i=1;i<=n;i++){ if(in[i]+1==out[i]){ ++start; start_x=i; } else if(out[i]+1==in[i]){ ++end; end_x=i; } else if(in[i]==out[i]){ ++cnt; } } if(!(start==1 && end==1 && cnt==n-2) && !(cnt==n)){ //!(start==1 && end==1 && cnt==n-2) 不是半欧拉图 //!(cnt==n) 不是欧拉图 //无欧拉路径 cout<<"No\n"; return ; } //有欧拉路径 for(ll i=1;i<=n;i++){ sort(e[i].begin(),e[i].end()); } dfs(start_x); while(!ans.empty()){ cout<<ans.top()<<' '; ans.pop(); } cout<<'\n'; } int main(){ ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); ll t=1; // cin>>t; while(t--){ solve(); } return 0; }
引用
BV1Y341177eW
【模版】欧拉路径题解@Marsrayd的博客
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了