欧拉回路

该篇博客探讨了图的深度优先遍历算法及其在解决欧拉路径(一笔画问题)中的应用。通过C++实现,展示了如何检查无向图是否存在欧拉回路的必要条件,包括图的连通性和所有节点的度数为偶数。同时,介绍了有向图中欧拉路径的必要条件,涉及基图的连通性及节点的出入度平衡。博客还提供了无向图邻接矩阵的递归遍历程序作为补充。
摘要由CSDN通过智能技术生成

欧拉回路

(1) 图的深度优先遍历

#include <iostream>
using namespace std;
int Node, Edge, Node1, Node2;
struct List_Node {
	int Node, Next;
	List_Node() {
		Node = 0;
		Next = 0;
	}
	List_Node(int node, int next) {
		Node = node;
		Next = next;
	}
};
List_Node List[1005];
int Head[105];
int New = 1;
void Insert(int Node1, int Node2) {
	List[New] = List_Node(Node2, Head[Node1]);
	Head[Node1] = New;
	New++;
}
bool Visited[105];
void DFS(int StartId) {
	Visited[StartId] = true;
	cout << StartId << ' ';
	for (int i = Head[StartId]; i != 0; i = List[i].Next) {
		if (Visited[List[i].Node] == false) {
			DFS(i);
		}
	}
}
void Search() {
	for (int i = 1; i <= Node; i++) {
		if (Visited[i] == 0) DFS(i);
	}
}
int main() {
	cin >> Node >> Edge;
	for (int i = 1; i <= Edge; i++) {
		cin >> Node1 >> Node2;
		Insert(Node1, Node2);
		Insert(Node2, Node1);
	}
	Search();
	return 0;
}

时间复杂度分析

每一个顶点被访问一次

每条边被访问两次

O(|V|+|E|)

O(|V|2) 对稠密图 |E|~|V|2

O(|V|) 对稀疏图 |E|~|V|

注意:

爆栈问题

(2) 应用举例——欧拉路 (一笔画) 问题

定义

欧拉路欧拉回路问题,
就是有一条路径(或回路)由所有边构成,且每边只用一次。也称为一笔画问题,即连续的一次画出图的所有边,经过每条边一次且仅一次。

结论1:无向图存在欧拉回路的必要条件:
  • 图是连通的。
  • 图中所有点的度均为偶数。
结论2:无向图欧拉路存在的必要条件:
  • 图是连通的。
  • 图中有且仅有两个度为奇数的点,并且这两个点一定是这条欧拉路的起点与终点。
证明
  • “勇往直前”
  • “圈套圈”
  • 把欧拉回路构造出来
结论3:有向图G,存在欧拉回路的必要条件:
  • 基图(原有向边改为无向边后所得的无向图)连通
  • 所有点的出度和入度相同
结论4:有向图G,存在欧拉路的必要条件:
  • 基图连通
  • 有且仅有一个点入度比出度大1,且这个点是欧拉路的终点
  • 有且仅有一个点入度比出度小1,且这个点是欧拉路的起点
  • 其他所有的点入度与出度相等
无向图的邻接矩阵递归程序
#include <cstdio>
using namespace std;
int Node, Edge, Node1, Node2;
bool Graph[105][105];
void DFS(int Now_Node) {
	for (int i = 1; i <= Node; i++) {
		if (Graph[Now_Node][i] || Graph[i][Now_Node]) {
			Graph[Now_Node][i] = 0;
			Graph[i][Now_Node] = 0;
		}
	}
	printf("%d ", Now_Node);
}
int main() {
	scanf("%d%d", &Node, &Edge);
	for (int i = 1; i <= Edge; i++) {
		scanf("%d%d", &Node1, &Node2);
		Graph[Node1][Node2] = Graph[Node2][Node1] = true;
	}
	DFS(1);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值