欧拉图与欧拉路
来源:互联网 发布:nginx rtmp 直播配置 编辑:程序博客网 时间:2024/03/28 22:55
定义:给定无孤立结点图G,若存在一条路,经过图中海边一次且仅一次,该条路称为欧拉路;若存在一条回路,经过图中海边一次且仅一次,该回路称为欧拉回路。具有欧拉回路的图称作欧拉图。
定理:无向图G具有一条欧拉路,当且仅当G是连通的,且有零个或两个奇数度结点。欧拉路和欧拉回路的概念,很易推广到有向图中去。
有向欧拉图
定义:给定有向图G,通过图中每边一次且仅一次的一条单向路(回路),称作单向欧拉路(回路)。
定理:有向图G具有一条单向欧拉回路,当且仅当是连通的,且每个结点入度等于出度。一个有向图G具有单向欧拉路,当且仅当它是连通的,而且除两个结点外,每个结点的入度等于出度,但这两个结点中,一个结点的入度比出度大1,另一个结点的入度比出度小1。
找欧拉路(或回路)可以用Euler算法,如下:
(1)寻找从i出发的环p1p2…px(p1=px=i)。
(2)标记顶的p1->x为待查的状态。
(3)对所有处在待查状态的节点pj递归调用过程Euler(pj)
将Euler(pj)找到的环q1q2…qx插入到环p1p2…px中,得到回路p1p2…pjq1…qypj+1…px。时间复杂度为O(m)。
输出时只要逆序输出pop即可,而且当边是按字母序建边时,输出的也是按字母序的答案。
纯dfs算法实现Euler()正确性的证明:
假设节点s为起点,则深搜到不能搜的时候那个节点就是s。为什么呢,只要将这点想通,基本就没什么问题了。我们知道如果一个节点入度减1,那么它的出度必然要减1,在以s为起点的路径中,se1v1e2v2....eivi,如果vi节点不是s节点且为深搜的最后节点,也就是说vi没有了出度,然而我们知道对于v1...v(i-1)节点入度一但减少,出度也就减少了,然而对于s起点来说只要出度减少却没有入度减少,vi的入度减少却没有了出度,所以证明vi节点不可能会成为不是s节点且为深搜的最后节点,即除非他还不是深搜的最后节点,到这里我们基本就可以确定了,vi要满足深搜最后节点必然为vi==s,这样的话vi的入度减少了,出度也减少了(因为s出度减少了),s的出度减少了,入度也减少了(因为vi的入度减少了)所以可以证明以s为起点的深搜最后节点也为s。
然后就是返回了,当沿着路径返回的途中如果vi节点还有出度的话,那么就以vi为起点开始深搜,根据上面的证明,我们可以知道最后的深搜节点肯定为vi起点了。
将回路se1v1e2v2.....eivi(ei1vi1ei2vi2...eiivi)e(i+1).....ejs,括号里面的就是返回途中发生的又一次回路咯,把它嵌入到里面自然大的回路也满足要求了。
欧拉路时同理。
定理:无向图G具有一条欧拉路,当且仅当G是连通的,且有零个或两个奇数度结点。欧拉路和欧拉回路的概念,很易推广到有向图中去。
有向欧拉图
定义:给定有向图G,通过图中每边一次且仅一次的一条单向路(回路),称作单向欧拉路(回路)。
定理:有向图G具有一条单向欧拉回路,当且仅当是连通的,且每个结点入度等于出度。一个有向图G具有单向欧拉路,当且仅当它是连通的,而且除两个结点外,每个结点的入度等于出度,但这两个结点中,一个结点的入度比出度大1,另一个结点的入度比出度小1。
找欧拉路(或回路)可以用Euler算法,如下:
(1)寻找从i出发的环p1p2…px(p1=px=i)。
(2)标记顶的p1->x为待查的状态。
(3)对所有处在待查状态的节点pj递归调用过程Euler(pj)
将Euler(pj)找到的环q1q2…qx插入到环p1p2…px中,得到回路p1p2…pjq1…qypj+1…px。时间复杂度为O(m)。
void Euler(int t){ int i; for(i=edge[t].next;i!=-1;i=edge[i].next) if(edge[i].t==-1) { edge[i].t=1; Eluer(edge[i].v); pop[top++]=edge[i].index; }}
输出时只要逆序输出pop即可,而且当边是按字母序建边时,输出的也是按字母序的答案。
纯dfs算法实现Euler()正确性的证明:
假设节点s为起点,则深搜到不能搜的时候那个节点就是s。为什么呢,只要将这点想通,基本就没什么问题了。我们知道如果一个节点入度减1,那么它的出度必然要减1,在以s为起点的路径中,se1v1e2v2....eivi,如果vi节点不是s节点且为深搜的最后节点,也就是说vi没有了出度,然而我们知道对于v1...v(i-1)节点入度一但减少,出度也就减少了,然而对于s起点来说只要出度减少却没有入度减少,vi的入度减少却没有了出度,所以证明vi节点不可能会成为不是s节点且为深搜的最后节点,即除非他还不是深搜的最后节点,到这里我们基本就可以确定了,vi要满足深搜最后节点必然为vi==s,这样的话vi的入度减少了,出度也减少了(因为s出度减少了),s的出度减少了,入度也减少了(因为vi的入度减少了)所以可以证明以s为起点的深搜最后节点也为s。
然后就是返回了,当沿着路径返回的途中如果vi节点还有出度的话,那么就以vi为起点开始深搜,根据上面的证明,我们可以知道最后的深搜节点肯定为vi起点了。
将回路se1v1e2v2.....eivi(ei1vi1ei2vi2...eiivi)e(i+1).....ejs,括号里面的就是返回途中发生的又一次回路咯,把它嵌入到里面自然大的回路也满足要求了。
欧拉路时同理。
- 欧拉图与欧拉路
- 与
- 与
- “” 与 “”
- ##与#
- >> 与 > >
- :与::
- &与&&
- && 与 &
- [[与((
- >>与>>>
- *与++
- *与++
- ++与++
- ->与 .
- :与::
- & | 与&& ||
- &&与&
- asp.net 抓取网页 自动识别编码
- Web应用中的轻量级消息队列
- (单纯二维) Mobile phones (1195)
- android消息推送demo
- oracle有Boolean类型
- 欧拉图与欧拉路
- 我与GO.COM
- css如何让文本框中的输入的文字始终垂直居中
- pysvn-workbench是客户端
- oracle数据库导入导出命令
- 在android4.0.4的SDK里裁剪APK,把不需要的APK去除掉
- Android消息推送
- 第一天——寄宿家庭
- android TimerTask 动态设置时间