• 欧拉路&欧拉回路


    1.
    如果图G中的一个路径包括每个边恰好一次,则该路径称为欧拉路径。

    如果一个回路是欧拉路径,则称为欧拉回路。
    具有欧拉回路的图称为欧拉图。
    具有欧拉路径但不具有欧拉回路的图称为半欧拉图。

    2.
    欧拉回路是数学家欧拉在研究著名的德国哥尼斯(Koenigsberg)七桥问题时发现的.

    3.
    以下判断基于此图的基图连通。

    在所有边连通的情况下

    如果所有的点的度数都为偶数,那么这是一条欧拉回路

    如果存在两个奇度点,那么从一个奇度点出发,最后到达另一个奇点,则称这是一条欧拉道路。

    无向图存在欧拉回路的充要条件:
    一个无向图存在欧拉回路,当且仅当该图所有顶点度数都为偶数,且该图是连通图。

    有向图存在欧拉回路的充要条件:
    一个有向图存在欧拉回路,所有顶点的入度等于出度且该图是连通图。

    4.欧拉回路的求解

    DFS搜索

    求解欧拉回路的思路为:

    利用欧拉定理判断出一个图存在欧拉通路或欧拉回路后,选择一个正确的起始顶点,

    用DFS算法遍历所有的边(每条边只遍历一次),遇到走不通就回退。在搜索前进方向上将遍历过的边按顺序记录下来。这组边的排列就组成了一条欧拉通路或回路。

    例题:

    骑马修栅栏 Riding the Fences

    题目背景

    Farmer John每年有很多栅栏要修理。他总是骑着马穿过每一个栅栏并修复它破损的地方。

    题目描述

    John是一个与其他农民一样懒的人。他讨厌骑马,因此从来不两次经过一个栅栏。你必须编一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每个栅栏都恰好被经过一次。John能从任何一个顶点(即两个栅栏的交点)开始骑马,在任意一个顶点结束。

    每一个栅栏连接两个顶点,顶点用1到500标号(虽然有的农场并没有500个顶点)。一个顶点上可连接任意多(>=1)个栅栏。两顶点间可能有多个栅栏。所有栅栏都是连通的(也就是你可以从任意一个栅栏到达另外的所有栅栏)。

    你的程序必须输出骑马的路径(用路上依次经过的顶点号码表示)。我们如果把输出的路径看成是一个500进制的数,那么当存在多组解的情况下,输出500进制表示法中最小的一个 (也就是输出第一位较小的,如果还有多组解,输出第二位较小的,等等)。

    输入数据保证至少有一个解。

    输入输出格式

    输入格式:

    第1行: 一个整数F(1 <= F <= 1024),表示栅栏的数目

    第2到F+1行: 每行两个整数i, j(1 <= i,j <= 500)表示这条栅栏连接i与j号顶点。

    输出格式:

    输出应当有F+1行,每行一个整数,依次表示路径经过的顶点号。注意数据可能有多组解,但是只有上面题目要求的那一组解是认为正确的。

    输入输出样例

    输入样例#1: 
    9
    1 2
    2 3
    3 4
    4 2
    4 5
    2 5
    5 6
    5 7
    4 6
    输出样例#1: 
    1
    2
    3
    4
    2
    5
    4
    6
    5
    7

    题目中要求是最小字典序 && 保证有欧拉路|欧拉回路
    那么记下每个点的入度,如果存在奇点,说明是欧拉路
    否则为欧拉回路
    然后按照上面所说的方法找欧拉回路即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<queue>
     6 #define ll long long
     7 #define DB double
     8 #define eps 1e-3
     9 using namespace std;
    10 inline int read()
    11 {
    12     int x=0,w=1;char ch=getchar();
    13     while(!isdigit(ch)){if(ch=='-') w=-1;ch=getchar();}
    14     while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    15     return x*w;
    16 }
    17 const int N=1510;
    18 int m,S,b[N][N],du[N],ans[N],k;
    19 void dfs(int u)
    20 {
    21     for(int i=1;i<=500;++i)
    22      if(b[u][i]>=1)
    23      {
    24          b[u][i]--;b[i][u]--;
    25          dfs(i);
    26      }
    27     ans[++k]=u;
    28 }
    29 int main()
    30 {
    31     m=read();
    32     for(int i=1;i<=m;++i)
    33     {
    34         int x,y;x=read();y=read();
    35         b[x][y]++;b[y][x]++;
    36         du[x]++;du[y]++;
    37     }
    38     S=1;
    39     for(int i=1;i<=500;++i)
    40      if(du[i]&1){S=i;break;}
    41     dfs(S);
    42     for(int i=k;i>=1;--i)
    43      printf("%d
    ",ans[i]);
    44     return 0;
    45 }
    View Code

    (๑′ᴗ‵๑)I Lᵒᵛᵉᵧₒᵤ❤

  • 相关阅读:
    数据结构--链表基础练习题
    LeetCode 10.28每日一题1207. 独一无二的出现次数【简单】
    数据结构--链表
    LeetCode 10.25每日一题845. 数组中的最长山脉【中等】
    LeetCode 10.22每日一题763. 划分字母区间【中等】
    解决map热点与uni-app中map标签冲突的问题。(Vue Render函数应用)
    【Codeforces 1329A】Dreamoon Likes Coloring
    【Codeforces Alpha Round #20 C】Dijkstra?
    【 Educational Codeforces Round 93 (Rated for Div. 2) D】Colored Rectangles
    【Codeforces Round #643 (Div. 2) C】Count Triangles
  • 原文地址:https://www.cnblogs.com/adelalove/p/8497000.html
Copyright © 2020-2023  润新知