zoukankan      html  css  js  c++  java
  • 欧拉回路

    一、引言

    欧拉回路问题是图论中最古老的问题,诞生于18世纪欧洲的科尼斯堡问题

    二、定义

    (G=(V,E))是一个图。

    欧拉回路:图G中经过每条边一次并且仅一次的回路。

    欧拉路径:图G中经过每条边一次并且仅一次的路径。

    欧拉图:存在欧拉回路的图。

    半欧拉图:存在欧拉路径但不存在欧拉回路的图。

    三、性质与定理

    假设下面讨论的图G不存在孤立点,否则,先将孤立点从图中删除。
    

    对于无向图:

    定理1:无向图G为欧拉图,当且仅当G为连通图且所有定点的度为偶数。

    推论1:无向图G为半欧拉图,当且仅当G为连通图且除了两个顶点的度为奇数之外,其它所有顶点的度为偶数。

    对于有向图:

    定理2:有向图G为欧拉图,当且仅当G的基图连通,且所有顶点的入度等于出度。

    推论2:有向图G为半欧拉图,当且仅当G的基图连通,且存在顶点u的入度比出度大1,v的入度比出度小1,其它所有顶点的入度等于出度。

    基图:忽略有向图所有边的方向,得到的无向图成为该有向图的基图。
    

    四、求欧拉回路

    两种:Hierholzer(套圈)算法和Fluery算法,前者编程简单,时间复杂度更优,后者应用性更广泛,这里不深入分析。

    Hierholzer算法:

    #include<iostream>
    #include<cstdio>
    #include<set>
    using namespace std;
    const int N=1025;
    multiset<int> h[N];
    int degree[N], road[N], k;
    
    void dfs(int x)
    {
        for(multiset<int>::iterator py=h[x].begin(); py!=h[x].end(); py=h[x].begin()){
            int y=*py;													 
            h[x].erase(py);												//删边x->y 
            h[y].erase(h[y].find(x));									//删边x->y
            dfs(y);														//从y递归 
        }
        road[k++]=x;													//往队列里插入答案 
    }
    
    int main(){
        int F, s=0, t=0;												//s起点,t终点 
        scanf("%d", &F);
        for(int i=1, a, b; i<=F; i++)	scanf("%d%d", &a, &b), degree[a]++, degree[b]++, h[a].insert(b), h[b].insert(a);
        for(int i=1; i<=1024; i++)										//注意模板题中栅栏结点的编号范围不是1~F 
        {
            if(degree[i]%2){											//发现奇点 
                if(!s)			s=i;
                else if(!t)		t=i;
                else 			return 0;								//发现奇点超过2个,无欧拉路径 
            }
    	}
    	if(s && !t)	return 0;											//只有1个奇点,无欧拉路径
    	if(!s)	s=1;													//没有奇点,有欧拉回路,指定1为起点 
        dfs(s);
        for(k=k-1; k>=0; k--)	printf("%d
    ", road[k]);				//倒序输出答案,也可以不用road数组,使用一个stack 
        return 0;
    }
    
    
    效率分析:共插入了2E条边,dfs共遍历2E条边。使用multiset可便于快速查找最小值,查找,删除边的复杂度为lgn,故程序时间复杂度为O(Elgn)。
    

  • 相关阅读:
    UVALive 6909 Kevin's Problem 数学排列组合
    UVALive 6908 Electric Bike dp
    UVALive 6907 Body Building tarjan
    UVALive 6906 Cluster Analysis 并查集
    八月微博
    hdu 5784 How Many Triangles 计算几何,平面有多少个锐角三角形
    hdu 5792 World is Exploding 树状数组
    hdu 5791 Two dp
    hdu 5787 K-wolf Number 数位dp
    hdu 5783 Divide the Sequence 贪心
  • 原文地址:https://www.cnblogs.com/lfyzoi/p/10789663.html
Copyright © 2011-2022 走看看