【图论】欧拉路

本文介绍了欧拉道路和欧拉回路在无向和有向连通图中的条件,包括节点度数规则,并提供了DFS和Hierholzer's算法实现。还讲述了如何通过删除割边构建欧拉路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

复习离散数学ing…顺手把acm中的整理发了…

欧拉道路&欧拉回路

  • 无向连通图的充分必要条件
    • 欧拉道路:度数为奇数的节点数=0或2
    • 欧拉回路:没有奇数度的节点
  • 有向连通图的充分必要条件
    • 欧拉道路:所有点入度=出度 or 有一个点入度=出度+1,有一个点出度=入度+1,其余入度=出度
    • 欧拉回路:所有点入度=出度
  • 构造:不断删边直到成为零图,删边的原则是若只有割边走割边,否则绝不走割边

dfs(非递归版)

stack<int> stk, ans; // dfs栈和答案栈
bool vst[M]; // 记录边是否访问过
void Euler()
{
	stk.push(1); // 起点
	while (!stk.empty())
	{
		int cur = stk.top();
		int i = head[cur];
		while (i && vst[i])
			i = edge[i].nxt; 
		if (i) // 找到下一条能走的路
		{
			stk.push(edge[i].to);
			vst[i] = vst[i ^ 1] = true;
			head[cur] = edge[i].nxt;
		}
		else
		{ // 与x相连的所有边均已访问,模拟回溯过程,并记录
			stk.pop();
			ans.push(cur); // 记录答案
		}
	}
}

Hierholzers

求欧拉道路,倒序输出,字典序最小

// 将起点设为1,若找到奇数度的节点就设它为起点
void dfs(int x)
{
	for (int i = 1; i <= n; i++)
		if (g[x][i])
		{
			g[x][i]--, g[i][x]--;
			dfs(i);
		}
	ans.push(x);
}

Fluery

stack<int> stk;
bool vst[M]; // 边是否访问过
void dfs(int u)
{
	stk.push(u);
	for (int i = head[u]; i; i = edge[i].nxt)
	{
		if (vst[i])
			continue;
		vst[i] = vst[i ^ 1] = true;
		dfs(edge[i].to);
		break;
	}
}
void Fleury(int st)
{
	stk.push(st);
	while (!stk.empty())
	{
		bool flag = false;
		int cur = stk.top();
		stk.pop();
		for (int i = head[cur]; i; i = edge[i].nxt)

			if(!vst[i])
			{
				flag = true;
				break;
			}
		if (!flag)
			printf("%d\n", u);
		else
			dfs(u);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值