zoukankan      html  css  js  c++  java
  • 欧拉路径详解

    什么是欧拉路径?欧拉路径就是一条能够不重不漏地经过图上的每一条边的路径,即小学奥数中的一笔画问题。而若这条路径的起点和终点相同,则将这条路径称为欧拉回路。

    如何判断一个图是否有欧拉路径呢?显然,与一笔画问题相同,一个图有欧拉路径需要以下几个条件:

    • 首先,这是一个连通图
    • 若是无向图,则这个图的度数为奇数的点的个数必须是0或2;若是有向图,则要么所有点的入度和出度相等,要么有且只有两个点的入度分别比出度大1和少1

    上面这两个条件很好证明。查找欧拉路径前,必须先保证该图满足以上两个条件,否则直接判误即可。

    查找欧拉路径的算法有Fluery算法和Hierholzer算法。下面介绍一下Hierholzer算法。

    算法流程:

    1. 对于无向图,判断度数为奇数的点的个数,若为0,则设任意一点为起点,若为2,则从这2个点中任取一个作为起点;对于有向图,判断入度和出度不同的点的个数,若为0,则设任意一点为起点,若为2,则设入度比出度小1的点为起点,另一点为终点。具体起点的选择要视题目要求而定。
    2. 从起点开始进行递归:对于当前节点x,扫描与x相连的所有边,当扫描到一条(x,y)时,删除该边,并递归y。扫描完所有边后,将x加入答案队列。
    3. 倒序输出答案队列。(因为这里是倒序输出,我们可以用栈来存储答案,当然用双端队列也可以)

    解析:

    从起点开始,每一次执行递归函数,相当于模拟一笔画的过程。递归的边界显然就是路径的终点,对于一个有欧拉路径的图,此时图上的所有边都已被删除,自然就不能继续递归。由于存储答案是在遍历以后进行的,答案存储也就是倒序的,因此要倒序输出答案。

    代码:

    #include<iostream>
    #include<stack>
    using namespace std;
    const int N=500;
    int n,tot,c=N,jp[N],cnt[N],edge[N][N];
    char a,b;
    stack<int> q;
    void dfs(int now)
    {
        for(int i=1;i<=N;i++)
            if(edge[now][i]==1)
            {
                edge[now][i]--,edge[i][now]--;
                dfs(i);
            }
        q.push(now);//加入答案队列
    }//算法过程
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a>>b;
            c=min(c,a);
            c=min(c,b);
            edge[a][b]++,edge[b][a]++;
            cnt[a]++;
            cnt[b]++;//统计每个节点的度数
        }
        for(int i=1;i<=N;i++)
            if(cnt[i]%2==1)
                jp[tot++]=i;//找出度数为奇数的节点
        if(tot!=2 && tot)
        {
            cout<<"No Solution";
            return 0;
        }//若该图没有欧拉路径则判误
        int stat;
        if(tot)
            stat=min(jp[0],jp[1]);
        else
            stat=c;//找出起点
        dfs(stat);
        while(!q.empty())
        {
            char ct=q.top();
            cout<<ct;
            q.pop();
        }//倒序输出
        return 0;
    }

    在上面的代码中,找出的是起点字典序最小的欧拉路径,具体情况应视题意而定。


    习题:


    2019.4.16 于厦门外国语学校石狮分校

  • 相关阅读:
    python测试开发django-43.xadmin添加小组件报错解决
    python测试开发django-42.xadmin自定义菜单项
    python测试开发django-41.crispy-forms设计标签式导航菜单(TabHolder)
    python测试开发django-40.模型(model)中choices使用
    python测试开发django-39.xadmin详情页面布局form_layout
    python测试开发django-45.xadmin添加小组件报错解决
    django后台xadmin如下配置(小结)
    禅道环境一键安装搭建指南
    Centos6.9部署ORTS5.0.22
    Linux 进程管理之四大名捕
  • 原文地址:https://www.cnblogs.com/TEoS/p/11376707.html
Copyright © 2011-2022 走看看