hiho欧拉路径(自留)
无向图
一个无向图存在欧拉路当且仅当该图是连通的且有且只有2个点的度数是奇数,此时这两个点只能作为欧拉路径的起点和终点。
若图中没有奇数度的点,那么起点和终点一定是同一个点,这样的欧拉路叫做欧拉回路
因为DFS本身就是一个入栈出栈的过程,所以我们直接利用DFS的性质来实现栈,其伪代码如下:
DFS(u): While (u存在未被删除的边e(u,v)) 删除边e(u,v) DFS(v) End PathSize ← PathSize + 1 Path[ PathSize ] ← u
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 2015.6.14 3 hiho一下 第五十周 4 欧拉路求路径 5 */ 6 7 #include<algorithm> 8 #include<iostream> 9 #include<cstring> 10 #include<cstdio> 11 #define maxn 1005 12 using namespace std; 13 14 struct edge{ 15 bool pass; 16 int num; 17 int v; 18 int next; 19 }e[maxn*10]; 20 int cor; 21 int head[maxn]; 22 int in[maxn]; 23 void add(int u,int v,int num){ 24 in[v]++; 25 e[cor].v=v; 26 e[cor].num=num; 27 e[cor].pass=false; 28 e[cor].next=head[u]; 29 head[u]=cor++; 30 } 31 int path[maxn*10],A; 32 void Init(){ 33 A=cor=0; 34 memset(head,-1,sizeof(head)); 35 memset(in,0,sizeof(in)); 36 } 37 38 void dfs(int u0){ 39 int u=head[u0]; 40 while(u!=-1){ 41 if(!e[u].pass){ 42 e[u].pass=true; 43 e[u^1].pass=true; 44 dfs(e[u].v); 45 } 46 u=e[u].next; 47 } 48 path[A++]=u0; 49 } 50 void Start(){ 51 int n,m; 52 while(~scanf("%d%d",&n,&m)){ 53 int u,v; 54 Init(); 55 for(int i=1;i<=m;i++){ 56 scanf("%d%d",&u,&v); 57 add(u,v,i); 58 add(v,u,i); 59 } 60 u=1; 61 for(int i=2;i<=n;i++) if(in[i]%2){ 62 u=i;break; 63 } 64 dfs(u); 65 for(int i=A-1;i>=0;i--){ 66 if(i==0) printf("%d",path[i]); 67 else printf("%d ",path[i]); 68 } 69 printf("\n"); 70 } 71 } 72 void End(){} 73 int main(){ 74 Start(); 75 End(); 76 return 0; 77 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /*Author :usedrose */ 2 /*Created Time :2015/6/2 13:41:03*/ 3 /*File Name :2.cpp*/ 4 #include <cstdio> 5 #include <iostream> 6 #include <algorithm> 7 #include <sstream> 8 #include <cstdlib> 9 #include <cstring> 10 #include <climits> 11 #include <vector> 12 #include <string> 13 #include <ctime> 14 #include <cmath> 15 #include <deque> 16 #include <queue> 17 #include <stack> 18 #include <set> 19 #include <map> 20 #define INF 0x3f3f3f3f 21 #define eps 1e-8 22 #define pi acos(-1.0) 23 #define MAXN 66010 24 #define OK cout << "ok" << endl; 25 #define o(a) cout << #a << " = " << a << endl 26 #define o1(a,b) cout << #a << " = " << a << " " << #b << " = " << b << endl 27 using namespace std; 28 typedef long long LL; 29 30 int n; 31 vector<int> G[MAXN]; 32 int ind[MAXN], outd[MAXN], cnt[MAXN]; 33 string ans; 34 35 void dfs(int i) 36 { 37 while (!G[i].empty()) { 38 int s = G[i].back(); 39 G[i].pop_back(); 40 dfs(s); 41 } 42 ans += (char)i%256; 43 } 44 45 int main() 46 { 47 //freopen("data.in","r",stdin); 48 //freopen("data.out","w",stdout); 49 string s; 50 int start = 0, u, v; 51 cin >> n; 52 for (int i = 0;i < n; ++ i) { 53 cin >> s; 54 u = s[0]*256 + s[1]; 55 start = u; 56 v = s[1]*256 + s[2]; 57 G[u].push_back(v); 58 outd[u]++;ind[v]++; 59 } 60 int l = 0, r = 0; 61 for (int i = 0;i < 66000; ++ i) { 62 int d = outd[i] - ind[i]; 63 if (d == 1) {l++; start = i; } 64 else if (d == -1) r++; 65 else if (d != 0) { 66 puts("NO"); 67 return 0; 68 } 69 if (l > 1 || r > 1) { 70 puts("NO"); 71 return 0; 72 } 73 } 74 dfs(start); 75 ans += (char)(start/256); 76 reverse(ans.begin(), ans.end()); 77 if (ans.length() != n + 2) puts("NO"); 78 else { 79 puts("YES"); 80 cout << ans << endl; 81 } 82 return 0; 83 }
有向图
对于有向图,其存在欧拉路的条件是,至多有两个点的入度不等于出度,且这两个点满足:其中一个点入度比出度多1,另一个点出度比入度多1
在有向图中找欧拉路的方法,也仍然可以使用Fleury算法。写成伪代码的话:
DFS(u): While (以u为起点,且未被删除的边e(u,v)) 删除边e(u,v) DFS(v) End PathSize ← PathSize + 1 Path[ PathSize ] ← u
但是,有一点要注意,在使用Fleury算法计算有向图的欧拉路时,我们需要将path[]倒序输出才能得到正确的路径。