浅谈欧拉图

定义

欧拉回路:图中能经过每条边且每条边只经过一次的回路

欧拉路径:图中能经过每条边且每条边只经过一次的路径

欧拉图:有欧拉回路的图叫做欧拉图

半欧拉图:没有欧拉回路但有欧拉路径的图

判定

无向图

欧拉图:图为连通图且每个点的度数为偶数

证明

必要性:使用反证法,假设一个欧拉图中有一个点的度数为奇数,设这个点进入了\(x\) 次,每进入一次必要出去(若从这个点为起点,开始时出去必要回来),则该点的度数应为\(2x\) ,与这个点的度数为奇数矛盾,故所有点的度数必为偶数

充分性:因为图为连通图,所以每个点的度数不为\(0\) ,且每个点的度数都为偶数,则整个图的度数和\(\ge 2n\) 所以这个图必定有环,假设选择一个环,删除掉这个环,接下的图必定还有环,选择一个与上一个环有公共端点的环,将他和上一个环合成一条回路,再删去它,重复这个操作,直到整个图被删掉,这个回路就是这个图的欧拉回路,故这个图必有欧拉回路

半欧拉图:图为连通图且除了两个点度数为奇数,其他每个点的度数为偶数

证明和欧拉图类似

有向图

欧拉图:图为连通图且每个点的入度和出度相同

半欧拉图:图为连通图且除了一个点入度比出度多\(1\) ,一个点出度比入度多\(1\) ,其他每个点的入度和出度相同

证明和无向图类似

生成

一般使用hierholzer算法。

思路:任选一个点,从这个点开始访问未访问的边,直到没边可以访问,此时必定回到了起点,然后再重复此过程即可

代码实现:

void dfs(int u)
{
	for(int i=h[u];i<a[u].size();i=h[u])
	{
		h[u]++;//删掉被访问的边
		dfs(a[u][i]);
	}
	q.push(u);
}

时间复杂度:\(O(m)\)

记得要删掉被访问过的边,不然会被卡到\(O(m^2)\)

练习

luoguP7771:板子题,把每条边按照字典序排序后找欧拉回路即可

luoguP1341:也是板子题,把每个字母看成一个点即可

luoguP1333:把每个颜色看成一个点,把木棍看成边,判断有没有欧拉回路即可

CF209C:把每个有边的连通块依次合并,合并过程中分类讨论一下即可

posted @ 2023-11-02 21:45  Shxt_Plus  阅读(139)  评论(0)    收藏  举报