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

    欧拉回路:图G经过每条边一次且仅一次的回路称为欧拉回路

    欧拉路径:图G经过每条边一次且仅一次的路径称为欧拉路径

    定理:

    无向图

    (1)无向图G为欧拉图,当且仅当G为连通图,且所有点的度数为偶数

    (2)无向图G为半欧拉图,当且仅当G为连通图,且除了两个节点度数为奇数外,其他节点度数均为偶数

    有向图

    (1)有向图G为欧拉图,当且仅当G的基图为连通图,且所有顶点的入度与出度相同

    (2)有向图G为半欧拉图,当且仅当G的基图为连通图,且存在顶点u的入度比出度大1,v的入度比出度小1,其他顶点的入度与出度相同

    欧拉回路的求解方法:

    (1)递归:

    伪代码:
    Euler(start);

      For顶点start的每个邻接点v

      IF边(start,v)未被标记Then{

        将边(start,v)标记;

        将边(v,start)标记;

        Euler(v);

        将(start,v)边加入栈S;

      }

    void dfs(int u) //记录节点(会缺少第一个起点) 
    {
        for(int &i=head[u];i;i=next[i]){
            int tp=ver[i];
            if(!vis[i]){
                vis[i]=vis[i^1]=1;
                dfs(tp);
                ans[++t]=tp;
            }
        }
    }

    (2)非递归:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = 100100;
    int head[maxn],ver[maxn],next[maxn],vis[maxn],tot;
    int sk[maxn],ans[maxn],m,n,top,t;
    void add(int x,int y)
    {
        ver[++tot]=y;next[tot]=head[x];head[x]=tot;
    } 
    void euler() //非递归写法 
    {
        sk[++top]=1; //记录起始节点 
        while(top>0){
            int x=sk[top];
            int i=head[x];
            while(i&&vis[i]) i=next[i];  //找到一条未访问的路径 
            if(i){  //沿着这条路递归 
                sk[++top]=ver[i];
                head[x]=next[i];
                vis[i]=vis[i^1]=true; //双向边,所以更新两个 
            }
            else{ //模拟回溯,记录结果
                top--;
                ans[++t]=x;
            }
        }
    }
    int main(void)
    {
        cin>>n>>m;
        tot=1;
        for(int i=1;i<=m;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            add(x,y);add(y,x);
        }
        euler();
        for(int i=t;i;i--) printf("%d ",ans[i]);
        return 0;
    }
    /*
    6 9
    1 2
    2 3
    3 4
    4 5
    5 6
    6 1
    1 3
    3 5
    1 5
    */
    View Code

    欧拉回路与哈密尔顿圈问题:

    欧拉回路是不重复的经过图中的每一条边;

    哈密尔顿圈是不重复的经过图中的每一个顶点;

    建模:解决实际问题时要尽量转换为欧拉回路的问题,而不是哈密尔顿圈问题,因为哈密尔顿圈问题没有有效的算法。

  • 相关阅读:
    市场定位和硬件设计的错误浅谈GM8126的封装
    在Protel的机械层中如何加“机械孔”的问题
    Protel中导入导出GERBER的相关问题
    程序猿与鸡
    AltiumDesinger中Comment属性与BOM表的联系
    用CSS实现动态效果的画廊
    Two scripts work with git pull/push
    emacs中remember.el 日期乱码问题
    使用Python解压,对比文件
    Save a tree as XML using XmlSerializer
  • 原文地址:https://www.cnblogs.com/2018zxy/p/10362863.html
Copyright © 2011-2022 走看看