浅谈欧拉图
定义
欧拉回路:图中能经过每条边且每条边只经过一次的回路
欧拉路径:图中能经过每条边且每条边只经过一次的路径
欧拉图:有欧拉回路的图叫做欧拉图
半欧拉图:没有欧拉回路但有欧拉路径的图
判定
无向图:
欧拉图:图为连通图且每个点的度数为偶数
证明:
必要性:使用反证法,假设一个欧拉图中有一个点的度数为奇数,设这个点进入了\(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:把每个有边的连通块依次合并,合并过程中分类讨论一下即可

浙公网安备 33010602011771号