欧拉路径
废话不扯,直接先了解一下定义
如果图G中的一个路径包括每个边恰好一次,则该路径称为欧拉路径(Euler path)
这需要跟哈密顿路区别一下,前者是边,后者是点
如果一个图中存在具有欧拉路径但不具有欧拉回路则称为半欧拉图
那么该如何求图中的欧拉路径呢
分类讨论一下
对于无向图
无向图中,一条欧拉路径上有且仅有两个度数为奇数的点(其他点度数都是偶数),这两个点就是这条欧拉路径的起点和终点
for( int i = 1 ; i <= n ; ++ i )
if( de[i] % 2 ) {
sta = i ;
break ;
}
对于有向图
有向图中,欧拉路径上仅有两点出度和入度不等,且其中一点入度等于出度-1,另一点入度等于出度+1,这条路径的起点就是出度大于入度的点,终点是出度小于入度的点(理解为每一点除起终点外,都是有进有出的)
求欧拉路径代码
void DFS( int x ) {//有向,无向通用,访问标记的是边
for( int i = 0 ; i < G[x].size() ; ++ i ) {
int s = G[x][i].num , E = G[x][i].e ;//s为子节点,E为x到s的路径
if( vis[E] )
continue ;
vis[E] = 1 ;
DFS( s );
}
S.push(x); //S栈
}//在查找路径之前先找出欧拉路径的起点
欧拉回路
定义:如果一个回路是欧拉路径,则称为欧拉回路(Euler circuit)
如果一个图中具有欧拉回路则称为欧拉图(E图)
了解一下判断
无向图
无向图中,所有点的度数都为偶数
有向图
所有点的出度和入度都相等
(代码和上面差不多,前面判断变一下)
代码模板
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#define MAXN 10005
using namespace std;
int n , m ;
int de[MAXN] , sta ;
bool vis[MAXN] , flag ;
struct node {
int num , e ;
node(){}
node( int Num , int Ee ) {
num = Num ;
e = Ee ;
}
};
vector <node> G[MAXN] ;
stack <int> S ;
bool cmp( node x , node y ) {
if( x.num > y.num )
return 1 ;
else return 0 ;
}
void DFS( int x ) {
for( int i = 0 ; i < G[x].size() ; ++ i ) {
int s = G[x][i].num , E = G[x][i].e ;
if( vis[E] )
continue ;
vis[E] = 1 ;
DFS( s );
}
S.push(x);
}
int main() {
scanf("%d%d", &n , &m );
for( int i = 1 ; i <= m ; ++ i ) {
int a , b ;
scanf("%d%d", &a , &b );
G[a].push_back(node(b,i));
G[b].push_back(node(a,i));
de[a] ++ , de[b] ++ ;
}
sta = 1 ;
for( int i = 1 ; i <= n ; ++ i )
if( de[i] % 2 ) {
sta = i ;
break ;
}
DFS( sta );
while( !S.empty() ) {
printf("%d ", S.top() );
S.pop() ;
}
}