欧拉回路

          欧拉回路具体来说比较简单,说起来就是以前玩过的一笔画,只不过真正的推出来公式和规律了(终于不用瞎找了).

          大佬博客 : https://www.cnblogs.com/zdblog/articles/3725858.html

          

欧拉通路: 通过图中每条边且只通过一次,并且经过每一顶点的通路

欧拉回路: 通过图中每条边且只通过一次,并且经过每一顶点的回路

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

无向图

  设G是连通无向图,则称经过G的每条边一次并且仅一次的路径为欧拉通路;

 如果欧拉通路是回路(起点和终点是同一个顶点),则称此回路是欧拉回路

  具有欧拉回路的无向图G成为欧拉图

有向图

(1)设D是有向图,D的基图连通,则称经过D的每条边一次并且仅有一次的有向路径为 有向欧拉通路

(2)如果有向欧拉通路是有向回路,则称此有向回路为  有向欧拉回路

(3)具有有向欧拉回路的图D称为有向欧拉图

定理

 无向图G存在欧拉通路的充要条件是:G为连通图,并且G仅有两个奇度结点(度数为奇数的顶点)或者无奇度结点。

推论

(1) 当G是仅有两个奇度结点的连通图时,G的欧拉通路必以此两个结点为端点;

(2)当G是无奇度结点的连通图时,G必有欧拉回路

(3)G为欧拉图(存在欧拉回路)的充分必要条件是  G为无奇度结点的连通图

 

(有向图) 定理

有向图D存在欧拉通路的充要条件是:D为有向图,D的基图连通,并且所有顶点的出度与入度相等;或者  除两个顶点外,其余顶点的出度与入度都相等,而这两个顶点中一个顶点的出度与入度之差为1,另一个顶点的出度与入度之差为-1.

推论

(1)当D除出、入度之差为1,-1的两个顶点之外,其余顶点的出度与入度相等时,D的有向欧拉通路必以出、入度之差为1的顶点作为始点,以出、入度之差为-1的顶点作为终点。

(2)当D的所有顶点的出、入度都相等时,D中存在有向欧拉回路。

(3)有向图D为有向欧拉图的充要条件是  D的基图为连通图,并且所有顶点的出、入度都相等。

 

 

欧拉回路的求解

两种方法:(1)DFS搜索  (Fleury)佛罗莱算法

(1)DFS搜索 思想求解欧拉回路的思路为:利用欧拉定理判断出一个图存在欧拉通路或欧拉回路后,选择一个正确的起始顶点,用DFS算法遍历所有的边(每条边只遍历一次),遇到走不通就回退。在搜索前进方向上将遍历过的边按顺序记录下来。这组边的排列就组成了一条欧拉通路或回路。

(2) (Fleury)佛罗莱算法

设G为一个无向欧拉图,求G中一条欧拉回路的算法如下:

(1) 任取G中一顶点v0,令P0=v0;

(2)假设沿Pi=v0e1v1e2v2......eivi走到顶点vi,按下面方法从E(G)-{e1,e2,...,ei}中选ei+1。

        ei+1与vi相关联

        除非无别的边可供选择,否则ei+1不应该是Gi=G-{e1,e2,...,ei}中的桥。

(3)当(2)不能再进行时算法停止。

        可以证明的是,当算法停止时,所得到的简单回路Pm=v0e1v1e2v2......emvm,(vm=v0)为G中一条欧拉回路。

 

备注知识:

  设无向图G(V,E)为连通图,若边集E1属于E,在图G中删除E1中所有的边后得到的子图是不连通的,而删除了E1的任一真子集后得到的子图是连通图,则称E1是G的一个割边集。若一条边构成一个割边集,则称该边为割边,或桥

 

      比较不错的概念,反正我自己写是肯定写不出来的,接下来有一道简单题可以试试手

      题目链接 : https://www.luogu.org/problemnew/show/P1341

      ac代码

      

#include<bits/stdc++.h>
using namespace std;
int tu[500][500];
int biao[500];
char c[10001];
int ge;
void dfs(int dang){
    for(int i=0;i<500;i++){
        if(tu[dang][i]==1){
            //printf("%c %c %d %d",dang,i,dang,i);
            tu[dang][i]=0;
            tu[i][dang]=0;
            dfs(i);
        }
    }
    c[ge++]=dang;
}
int main()
{
    int n;
    scanf("%d ",&n);
    memset(tu,0,sizeof(tu));
    memset(biao,0,sizeof(biao));
    for(int i=0;i<n;i++){
        char x[5];
        scanf("%s",x);
        tu[x[0]][x[1]]=1;
        tu[x[1]][x[0]]=1;
        biao[x[0]]++;
        biao[x[1]]++;
    }
    int minn=100010;
    int ha=0;
    for(int i=0;i<500;i++){
        if(biao[i]%2!=0){
            ha++;
            minn=min(minn,i);
        }
    }
    if(ha!=0&&ha!=2){
        printf("No Solution\n");
        return 0;
    }
    if(minn==100010){
        for(int i=0;i<500;i++){
            if(biao[i]!=0&&biao[i]%2==0){
                minn=i;
                break;
            }
        }
    }
    ge=0;
    dfs(minn);
    if(ge>=n+1){
        for(int i=ge-1;i>=0;i--){
            printf("%c",c[i]);
        }
        printf("\n");
    }
    else{
        printf("No Solution\n");
    }
    return 0;
}

 

posted @ 2019-01-17 08:53  快乐的黄鳝  阅读(380)  评论(0编辑  收藏  举报