zoukankan      html  css  js  c++  java
  • 「图论」欧拉路

    定义

    通路:一条从(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)

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

  • 相关阅读:
    oracle中Blob和Clob类型的区别
    为什么要分库分表
    Enable file editing in Visual Studio's debug mode
    SQL Server Dead Lock Log
    Debug .NET Framework Source
    SQL Server text field里面有换行符的时候copy到excel数据会散乱
    诊断和修复Web测试记录器(Web Test Recorder)问题
    Can't load Microsoft.ReportViewer.ProcessingObjectModel.dll
    'telnet' is not recognized as an internal or external command
    Linq to XML
  • 原文地址:https://www.cnblogs.com/knife-rose/p/15081251.html
Copyright © 2011-2022 走看看