欧拉路径

概念

  1. 欧拉路径:从某一点出发经过一条不间断的路径,这条路径刚好访问整个图的所有遍一次且仅一次。
    • 这个图可以是有向图/无向图。
    • 一个图可以有多个欧拉路径
  2. 欧拉回路:起点和终点为同一个点的欧拉路径。
    • 一个图可以有多个欧拉回路
  3. 欧拉图:具有欧拉回路的图
  4. 半欧拉图:具有欧拉路径但是不具有欧拉回路的图

存在条件

  1. 所有有向边改为无向边后图是否连通:可以用dfs或并查集来找
  2. 欧拉图
    • 无向图:所有顶点度数都是偶数
    • 有向图:图的所有顶点都满足“入度=出度”
  3. 半欧拉图
    • 无向图:有且仅有两个点的度数是奇数,其余的点度数都为偶数
    • 有向图:有且仅有一个点“入度=出度+1” 并且 有且仅有一个点“出度=入度+1”,其余的点“入度=出度”

半欧拉图的起点 & 终点

  • 无向图:两个度数为奇数的一个 --> 另一个
  • 有向图:“出度=入度+1” --> “入度=出度+1”

欧拉路径算法

  1. 判断给定图是否是欧拉图/半欧拉图(如果没有连通的限制还要判定是否是连通图)
  2. 确定路径起点
    • 欧拉图任意
    • 半欧拉图见上
  3. 答案栈answer存储途径节点
  4. 对图进行dfs,节点允许重复经过,边不允许。每访问一条边就删掉,然后对这条边另一端的点进行遍历。每一个节点完成遍历且没有相连边时,将这个节点加入answer
  5. 遍历结束,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的博客

posted @ 2025-02-08 06:42  Gusare  阅读(102)  评论(0)    收藏  举报