简单的Fleury算法模板

假设数据输入时采用如下的格式进行输入:首先输入顶点个数n和边数m,然后输入每条边,每条边的数据占一行,格式为:u,v,表示从顶点u到顶点v的一条有向边

这里把欧拉回路的路径输出了出来:

手写栈:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 #define N 1005
 6 int first[N],k,degree[N],visit[N];
 7 struct stack{
 8     int top,node[N];
 9 }s;
10 struct Path{
11     int y,next,flag;
12 }path[N<<1];
13 void add(int x,int y)
14 {
15     path[k].y=y,path[k].next=first[x],path[k].flag=k;
16     first[x]=k;
17     k++;
18     path[k].y=x,path[k].next=first[y],path[k].flag=k-1;
19     first[y]=k;
20     k++;
21 }
22 void dfs(int u)
23 {
24     s.node[++s.top]=u;
25     for(int i=first[u];i!=-1;i=path[i].next){
26         if(!visit[path[i].flag]){
27             visit[path[i].flag]=1;
28             dfs(path[i].y);
29             break;
30         }
31     }
32 }
33 void Fleury(int x)
34 {
35     int b;
36     s.top=0;
37     s.node[s.top]=x;
38     while(s.top>=0){
39         b=0;
40         int u=s.node[s.top];
41         for(int i=first[u];i!=-1;i=path[i].next){
42             if(!visit[path[i].flag]){
43                 b=1;
44                 break;
45             }
46         }
47         if(b==0){//如果没有点可以扩展
48             printf("%d ",s.node[s.top]);
49             s.top--;
50         }
51         else{
52             s.top--;
53             dfs(s.node[s.top+1]);
54         }
55     }
56 }
57 int main()
58 {
59     int n,m,u,v;
60     scanf("%d%d",&n,&m);
61     k=0;
62     memset(first,-1,sizeof(first));
63     memset(degree,0,sizeof(degree));
64     memset(visit,0,sizeof(visit));
65     for(int i=0;i<m;i++){
66         scanf("%d%d",&u,&v);
67         add(u,v);
68         degree[u]++,degree[v]++;
69     }
70     int odd=0,st=1;
71     for(int i=1;i<=n;i++){
72         if(degree[i]&1) odd++,st=i;
73     }
74     if(odd==0||odd==2) {Fleury(st);}
75     else printf("No Euler path\n");
76     return 0;
77 }

stl容器栈:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <stack>
 5 using namespace std;
 6 #define N 1005
 7 int first[N],k,degree[N],visit[N];
 8 stack<int> s;
 9 struct Path{
10     int y,next,flag;
11 }path[N<<1];
12 void add(int x,int y)
13 {
14     path[k].y=y,path[k].next=first[x],path[k].flag=k;
15     first[x]=k;
16     k++;
17     path[k].y=x,path[k].next=first[y],path[k].flag=k-1;
18     first[y]=k;
19     k++;
20 }
21 void dfs(int u)
22 {
23     s.push(u);
24     for(int i=first[u];i!=-1;i=path[i].next){
25         if(!visit[path[i].flag]){
26             visit[path[i].flag]=1;
27             dfs(path[i].y);
28             break;
29         }
30     }
31 }
32 void Fleury(int x)
33 {
34     int b;
35     s.push(x);
36     while(!s.empty()){
37         b=0;
38         int u=s.top();
39         for(int i=first[u];i!=-1;i=path[i].next){
40             if(!visit[path[i].flag]){
41                 b=1;
42                 break;
43             }
44         }
45         if(b==0){//如果没有点可以扩展
46             printf("%d ",s.top());
47             s.pop();
48         }
49         else{
50             s.pop();
51             dfs(u);
52         }
53     }
54 }
55 int main()
56 {
57     int n,m,u,v;
58     scanf("%d%d",&n,&m);
59     k=0;
60     memset(first,-1,sizeof(first));
61     memset(degree,0,sizeof(degree));
62     memset(visit,0,sizeof(visit));
63     for(int i=0;i<m;i++){
64         scanf("%d%d",&u,&v);
65         add(u,v);
66         degree[u]++,degree[v]++;
67     }
68     int odd=0,st=1;
69     for(int i=1;i<=n;i++){
70         if(degree[i]&1) odd++,st=i;
71     }
72     if(odd==0||odd==2) {Fleury(st);}
73     else printf("No Euler path\n");
74     return 0;
75 }

输入:
9 14
1 2
1 8
2 3
2 8
2 9
3 4
4 5
4 6
4 9
5 6
6 7
6 9
7 8
8 9

结果:

1 2 3 4 5 6 4 9 2 8 7 6 9 8 1

时间: 2024-08-04 16:58:31

简单的Fleury算法模板的相关文章

kruskal 算法模板

http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2896 #include <stdio.h> #include <string.h> #include <stdlib.h> struct node { int u,v,w; }q[200001]; int bin[50001]; int n,m,ans; int cmp(const void *a,const void

Floyd算法模板

Floyd可以求出任意两点间的最短距离,代码也相对简单,对于稀疏图来说效率也还是不错的,但由于三个for循环导致时间复杂度较高,不适合稠密图. Floyd算法模板(精简版): void Floyd() { int dist[maxn][maxn]; // dist存储i到j的最短距离 for(int k = 1; k <= n; k++) for(int i = 1;i <= n; i++) for(int j = 1; j <= n; j++) if(dist[i][k] + dist

欧拉回路&amp;Fleury算法&amp;实现

基本知识 欧拉回路:图G,若存在一条路,经过G中每条边有且仅有一次,称这条路为欧拉路,如果存在一条回路经过G每条边有且仅有一次, 称这条回路为欧拉回路.具有欧拉回路的图成为欧拉图. 判断欧拉路是否存在的方法 有向图:图连通,有一个顶点出度大入度1,有一个顶点入度大出度1,其余都是出度=入度. 无向图:图连通,只有两个顶点是奇数度,其余都是偶数度的. 判断欧拉回路是否存在的方法 有向图:图连通,所有的顶点出度=入度. 无向图:图连通,所有顶点都是偶数度. 程序实现一般是如下过程: 1.利用并查集判

linux下面简单通用的Makefile模板

简单通用的Makefile模板: ############################################## # # 单目录通用Makefile # 目标文件可自己的设定 # 始须调试程序,修改 CFLAGS 变量为-Wall -g # # wuyq 20140825 ############################################## # EXECUTABLE为目标的可执行文件名, 可以根据具体的情况对其进行修改. EXECUTABLE := spi

tarjan算法模板

var {left表示点 root 没离开栈 vis表示点 root 有没有被访问过} i,n,m,now,time,color,top:longint; v:array[0..10001] of record start:longint;end; e:array[0..100001] of record y,next:longint;end; dfn,low,stack,encolor:array[0..10001] of longint; vis,left:array[0..10001] o

prim算法模板

var g:array[1..10,1..10] of longint; d:array[1..10] of longint; f:array[1..10] of boolean; procedure prim; var i,j,k,min:longint; begin fillchar(g,sizeof(g),0); fillchar(f,sizeof(f),0); for i:=1 to n do d[i]:=g[1,i]; f[1]:=true; for i:=2 to n do begi

bellman-ford算法模板

有SPFA模板,bellman-ford模板显然是多余的. var e:array[1..maxe]of record a,b,w:longint;end; { 距源点s距离 } dis:array[1..maxn]of longint; { 前驱 } pre:array[1..maxn]of longint; m,n,s:longint; procedure relax(u,v,w:longint); begin if dis[u]+w<dis[v] then begin dis[v]:=di

分享一套简单的CodeSmith三层模板

Model: <%@ Template Language="C#" TargetLanguage="C#" %> <%@ Assembly Name="SchemaExplorer" %> <%@ Import Namespace="SchemaExplorer" %> <%@ Property Name="SourceTable" Type="Schem

Floyd判最小环算法模板

算法思想:如果存在最小环,会在编号最大的点u更新最短路径前找到这个环,发现的方法是,更新最短路径前,遍历i,j点对,一定会发现某对i到j的最短路径长度dis[i][j]+mp[j][u]+mp[u][i] != INF,这时i,j是图中挨着u的两个点,因为在之前最短路更新过程中,u没有参与更新,所以dis[i][j]所表示的路径中不会出现u,如果成立,则一定是一个环.用Floyd算法来实现.但是对于负环此算法失效,因为有负环时,dis[i][j]已经不能保证i到j的路径上不会经过同一个点多次了.