无向图欧拉道路(欧拉回路)的判定与路径打印

欧拉道路描述的是无向图的一个顶点出发的一条道路能够经过每条边恰好一次

欧拉回路指的是任意点出发都满足上述性质

如果一个图是欧拉道路或者欧拉回路,必须满足两个条件

第一个条件,这个图是连通图

第二个条件,所有点的度数满足“一定的关系”

然后我们阐述一下“一定的关系”是什么

检查这个图所有点的度数,求出这个图度数给奇数的点的个数,我们也可以称之为奇点数

如果没有奇点,这个图是一个欧拉回路,从任意点出发可以经过所有的边并回到这个点

如果存在两个奇点(这两个奇点具有这样的性质,这两个点分别为起点和终点,其中起点的出度比入度大1,终点的入度比出度大1),那么这个图是一个欧拉道路

然后我们看一下程序怎么写,这里只给出了求欧拉回路的程序

思路是这样的,先判连通,然后计算点的度数,如果有奇点就肯定不是欧拉回路了(有可能是欧拉道路)

int n,m;
int G[maxn][maxn],a[maxn],vis[maxn],vi[maxn][maxn];

n个点m条边

G邻接矩阵,a是统计每一个点度数的,vis是判连通时用到的数组,而vi是打印欧拉路径的时候的判重数组

void dfs(int u)
{
    for(int i=1;i<=n;i++)
    if(G[u][i]&&!vis[i]){vis[i]=1;dfs(i);}
}

判连通,超热血的DFS

void euler(int u)  //如果不是欧拉回路,参数必须传道路起点
{
    for(int v=1;v<=n;v++)
    if(G[u][v]&&!vi[u][v]){vi[u][v]=vi[v][u]=1;euler(v);printf("%d %d\n",u,v);}
    //有向图中去掉vi[v][u],真正路径把printf压栈
}

打印欧拉路径的函数,也十分热血

下面给出完整实现,这个程序是判断欧拉回路的一定要注意

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 const int maxn=1005;
 5 int n,m;
 6 int G[maxn][maxn],a[maxn],vis[maxn],vi[maxn][maxn];
 7 void dfs(int u)
 8 {
 9     for(int i=1;i<=n;i++)
10     if(G[u][i]&&!vis[i]){vis[i]=1;dfs(i);}
11 }
12 void euler(int u)  //如果不是欧拉回路,参数必须传道路起点
13 {
14     for(int v=1;v<=n;v++)
15     if(G[u][v]&&!vi[u][v]){vi[u][v]=vi[v][u]=1;euler(v);printf("%d %d\n",u,v);}
16     //有向图中去掉vi[v][u],真正路径把printf压栈
17 }
18 int main()
19 {
20     while(cin>>n)
21     {
22         memset(G,0,sizeof(G));
23         memset(a,0,sizeof(a));
24         memset(vis,0,sizeof(vis));
25         if(n==0) break;
26         cin>>m;
27         for(int i=1;i<=m;i++){int x,y;cin>>x>>y;G[x][y]=1;G[y][x]=1;}
28         bool flag=1;int tmp=0;
29         vis[1]=1;dfs(1);
30         for(int i=1;i<=n;i++)
31         if(vis[i]==0) flag=0;
32         if(flag)
33         {
34             for(int i=1;i<=n;i++)
35             for(int j=1;j<=n;j++)
36             if(G[i][j]) a[i]++;
37             for(int i=1;i<=n;i++)
38             if(a[i]%2!=0) tmp++;
39         }
40         if(flag&&tmp==0) cout<<1<<endl;
41         else cout<<0<<endl;
42     }
43     return 0;
44 }

如果一个问题可以转换成求欧拉道路或者欧拉回路的形式,那答案就显然了

原文地址:https://www.cnblogs.com/aininot260/p/9388322.html

时间: 2024-10-01 10:54:12

无向图欧拉道路(欧拉回路)的判定与路径打印的相关文章

无向图与有向图判定欧拉道路与欧拉回路的方法

欧拉道路: 从无向图中的一个节点出发走一条道路,每条边恰好经过一次,这样的线路成为欧拉道路. 下面给出欧拉道路的判定方法: 有向图: 图必须是连通的,而且最多只能有两个点入度不等于出度,而且这两个点其中一个点的入度+1=出度,另一个点的出度+1=入度,如果有的点出度!=入度&&出度与入度的绝对值差还不等于1,则这个图不是欧拉道路. 无向图: 图必须是连通的,而且最多有两个奇度点,则是欧拉道路. 判定图连通的方法: 无向图用dfs访问,看看点是否全部被访问. 有向图先转化为无向图,然后再用d

欧拉道路与欧拉回路

欧拉道路与欧拉回路 欧拉道路:通过图G中每条边一次且仅一次的道路称作该图的欧拉道路. 欧拉回路:通过图G中每条边一次且仅一次的回路称作该图的欧拉回路. 欧拉图:存在欧拉回路的图称为欧拉图. 欧拉在1736年给出了欧拉道路/回路存在的必要条件,在1873年希尔霍尔策首次给出了刻画欧拉图的充要条件. 定理 (a)无向图G是欧拉图(存在欧拉回路)当且仅当G是连通的且所有顶点都是偶数度 (b)无向图G存在欧拉道路当且仅当G是连通的且奇数度顶点不超过2个 下面证明(a): 1.(必要性)如果是欧拉图,从一

UVa 10129 Play On Words【欧拉道路 并查集 】

题意:给出n个单词,问这n个单词能否首尾接龙,即能否构成欧拉道路 按照紫书上的思路:用并查集来做,取每一个单词的第一个字母,和最后一个字母进行并查集的操作 但这道题目是欧拉道路(下面摘自http://blog.csdn.net/hcbbt/article/details/9316301) 关于欧拉道路(from Titanium大神): 判断有向图是否有欧拉路 1.判断有向图的基图(即有向图转化为无向图)连通性,用简单的DFS即可.如果图都不连通,一定不存在欧拉路 2.在条件1的基础上   对于

UVA 10441 - Catenyms(欧拉道路)

UVA 10441 - Catenyms 题目链接 题意:给定一些单词,求拼接起来,字典序最小的,注意这里的字典序为一个个单词比过去,并非一个个字母 思路:欧拉回路.利用并查集判联通,然后欧拉道路判定,最后dfs输出路径 代码: #include <cstdio> #include <cstring> #include <string> #include <vector> #include <iostream> #include <algo

dfs求欧拉道路

从一个节点出发的一条路径每条边只经过一次,则把这条路称作欧拉道路. 欧拉道路存在着这样的性质除起点和终点以外所有经过的节点的出度和入度相等,也就是说除起点和终点以外的节点的度都为偶数. 同时一个无向图是连通的,且最多存在两个奇点,则一定存在欧拉道路,并且如果是有两个奇点,欧拉道路一定是从一个奇点出发到达另外一个奇点,如果没有奇点,则从任何一个节点出发然后最终回到该点(欧拉回路),奇点为一的情况是不存在的. 对于存在欧拉道路的情况,最多只能有两个点的入度不等于出度,而且必须是其中一个节点的入度比出

luogu P2731 骑马修栅栏 Riding the Fences | 欧拉道路

luogu P2731 骑马修栅栏 Riding the Fences luogu P1341 无序字母对 度数:一个点上连接边的个数 1.欧拉道路:相当于一笔画 无向图:除了两个或没有点为奇点(度数为奇)以外,其余度数均为偶 有向图:只有两个点或没有点入度不等于出度,起点入度=出度-1,终点入度=出度+1 2.欧拉回路: 无向图:奇点个数为0 有向图:所有点出度=入度(起点终点重合) #include<cstdio> #include<iostream> using namesp

UVA 10129 Play on Words(欧拉道路)

题意:给你n个字符串,问你是否可以出现一条链,保证链中每个字符串的第一个元素与上一个字符串的最后一个元素相同,注意可能重复出现同一个字符串 题解:以每一个字符串第一个元素指向最后一个元素形成一个有向图,判断这个有向图是否可以形成欧拉路就好 注意可能有重边与自环,因此求欧拉路时判断的是是否使用完了所有的边,求起点时注意出度与入度的计算 欧拉道路是从一个点一笔画完整张图(欧拉回路保证回到起点),注意除了起点与终点以外所有的点出度入度相等 起点出度大入度1,终点相反(所有的点出入度相等也可以),根据这

POJ 2513 Colored Sticks(欧拉道路+字典树+并查集)

http://poj.org/problem?id=2513 题意: 给定一些木棒,木棒两端都涂上颜色,求是否能将木棒首尾相接,连成一条直线,要求不同木棒相接的一边必须是相同颜色的. 思路: 题目很明显的是欧拉道路的问题. 欧拉道路的关键是: ①图是连通的. ②最多只能有两个奇点.(不能只存在一个奇点) 本来是想用map映射的,但是太多了,比较费时,这里用字典树的话会比较省时,判断图是否连通可以用并查集来完成. 1 #include<iostream> 2 #include<algori

Nyoj42 一笔画问题 (欧拉道路)

http://acm.nyist.net/JudgeOnline/problem.php?pid=42题目链接 #include <cstdio> #include <cstring> #define CLR(arr) memset(arr,0,sizeof(arr)) #define P 1001 int G[P],fa[P]; int find(int x){return x==fa[x]?x:x=find(fa[x]);} int main() {     int n,a,b