• 「图论」欧拉路


    定义

    通路:一条从(v_i)(v_j)的不经过重复边的一条路经,长度为通路中边的个数

    回路:起点和终点相同的通路

    欧拉通路:经过图(G)所有边一次的通路

    欧拉回路:经过图(G)所有边一次的回路

    欧拉图((E)图):具有欧拉回路的图

    半欧拉图:具有欧拉通路但不具有欧拉回路的图

    平凡图:只有一个节点的图

    判定

    无向图:(G)为连通图,有且仅有两个奇数度顶点,则图存在欧拉通路,无奇数度节点,则图存在欧拉回路

    有向图:(G)为连通图,起点出度比入度大(1),终点入度比出度大(1),则存在欧拉通路,所有顶点入度等于出度,则存在欧拉回路

    证明: 无向图(G)为连通图,无奇数度节点,则图存在欧拉回路

    必要性显然

    充分性:

    由于所有节点都是偶数度节点,那么必然存在一个简单环,如果这个环就是欧拉回路结论已经成立,否则删掉该环上所有边,子图中的节点一定不存在奇数度节点

    由于图的连通性,子图与该环必定有公共顶点,以公共顶点为起点在子图中寻找简单环递归做

    又因为子图中的环与原图简单环有公共顶点,所以二者可以并在一起,最终形成欧拉回路

    证明: 无向图(G)为连通图,有且仅有两个奇数度顶点,则图存在欧拉通路

    必要性显然

    充分性:

    将两个奇数度顶点直接连边,图(G)中必定存在欧拉回路

    有向图同理

    定理

    1.一个非平凡联通图是欧拉图当且仅当它每条边属于奇数个环

    证明:几个环交接处的边的两个顶点的度数为环数+1

    实现

    判断图中存在欧拉路或欧拉回路后,只要选择正确的起点无脑递归,无路可走就回溯,回溯时记录路径

    
    inline void dfs(int now)
    {
    	for(int i=l;i<=r;++i)
    	{
    		if(g[now][i])
    		{
    			--g[now][i];
    			--g[i][now];
    			dfs(i);
    		}
    	}
    	ret[++sum]=now;
    }
    
    

    最后将路径倒序输出

    while(sum) printf("%d
    ",ret[sum--]);
    
    

    为什么一定要倒序输出不是直接输出?

    考虑以下情况(无向图):

    标准(dfs)很可能(1)之后进入(2),转了一圈之后发现无法返回,那么我们(dfs)树上的顺序很可能是:

    (1、2、3、4、2、5、6、1)

    但这很明显不是欧拉路的顺序

    若我们用栈,在回溯时将节点入栈,先将(2、4、3、2、1)压入栈底

    而后将(6、5、1)进栈

    那么倒序输出的顺序就是(1、5、6、1、2、3、4、2)

    也就是说在求欧拉通路时,死路一定要走的但不能放在最早走,而是一旦遇到通过栈在走完回路之后通过

  • 相关阅读:
    矩阵构造方法(转载)
    欧拉函数
    POJ3233:Matrix Power Series(矩阵快速幂+二分)
    矩阵快速幂(转载)
    素数筛法模板
    快速幂取模算法
    hdu1286(找新朋友)&&POJ2407Relatives(欧拉函数模版题)
    判断两线段相交
    POJ3070:Fibonacci(矩阵快速幂模板题)
    HDU1575:Tr A(矩阵快速幂模板题)
  • 原文地址:https://www.cnblogs.com/knife-rose/p/15081251.html
Copyright © 2020-2023  润新知