复习心得 - 欧拉路

定义

通过所有边的路径(回路)。

有向图的判定

要是 \({\tt ind}_i+1={\tt outd}_i\),就是起点,要是 \({\tt ind}_i\neq{\tt outd}_i\),那么这个点不能作为中间点。

显然一个欧拉路不能作为中间点的数量 \(z\) 必须为 \(0\) 或 \(2\)。

  • \(z=0\),就是欧拉回路。
  • \(z=2\) 且起点为 \(1\) 个,就是欧拉路径。

具体原因可以想想一笔画。

有向图的查询

当 \(z=0\),那么我们找不到起点。

可以找一个 \({\tt ind}_i\neq 0\) 的点,因为欧拉回路从任一点出都能回到这个点。

然后从起点 \(x\) 搜索。

我们发现直接 dfs 就可以求出路径,倒序输出 dfs 栈即可。

有向图代码

#include<bits/stdc++.h>
using namespace std;
string s;
int n,deg[2][50],st,stc,notl;
vector<int>e[50];
int dfn[1000005],cur,f[50];
void dfs(int p){
	for(;f[p]<deg[1][p];){
		int v=e[p][f[p]++];
		dfs(v);
		dfn[++cur]=v;
	}
}
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>s;
		int u=s[0]-'a'+1,v=s[(int)s.size()-1]-'a'+1;
		deg[1][u]++;
		deg[0][v]++;
		e[u].push_back(v);
	}
	for(int i=1;i<=26;i++){
		if(deg[0][i]+1==deg[1][i])
			st=i,stc++;
		if(deg[0][i]!=deg[1][i])	
			notl++;	
	}
	if(notl&&!(stc==1&&notl==2))
		return cout<<"No\n",0;
	if(!st)
		for(int i=1;i<=26;i++)if(deg[0][i])
			st=i;
	dfn[++cur]=st;
	dfs(st);
	if(cur!=n+1)
		return cout<<"No\n",0;
	cout<<"Yes\n";
	for(int i=cur;i>=1;i--)
	    cout<<char(dfn[i]+'a'-1)<<" ";
	return 0;
}

无向图的判定

我们发现这时 \(\tt deg\) 统一了。

首先,要是 \({\tt deg}_i\bmod 2=1\),那么我们认为这个点是奇点,设有 \(x\) 个,同时我们要用这个设为搜索起点。

  • \(x=0\),那么从任意点都可以出发,同理需要整改一个搜索起点。欧拉回路。
  • \(x=2\),那么我们可以从一个奇点出发走到另一个。欧拉路径。

无向图的查询

我们注意到这时就无法简单标记已经走过的边了。

考虑标记 \((u,v)\) 和 \((v,u)\),直接做。

无向图代码

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,deg[N],st,stc,m;
vector<pair<int,int>>e[N];
int dfn[N<<2],cur,f[N];
bool vis[N];
void dfs(int p){
	for(auto v:e[p])if(!vis[v.second]){
		vis[v.second]=1;
		dfs(v.first);
		dfn[++cur]=v.first;
	}
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u,v;
		cin>>u>>v;
		deg[u]++;
		deg[v]++;
		e[u].push_back({v,i});
		e[v].push_back({u,i});
	}
	for(int i=1;i<=n;i++)
		if(deg[i]&1)
			st=i,++stc;
	if(!(stc==0||stc==2))
		return cout<<"No\n",0;
	if(!st)
		for(int i=1;i<=n;i++)if(deg[i])
			st=i;
	dfn[++cur]=st;
	dfs(st);
	if(cur!=m+1)
		return cout<<"No\n",0;
	cout<<"Yes\n";
	// for(int i=cur;i>=1;i--)
		// cout<<dfn[i]<<" ";
	return 0;
}

https://www.luogu.com.cn/article/su63ld2h

posted @ 2026-10-08 21:33  Ivan422  阅读(2)  评论(0)    收藏  举报