欧拉回路 \huge \textbf{欧拉回路} 欧拉回路
欧拉回路即一笔画问题 \textsf{欧拉回路即一笔画问题} 欧拉回路即一笔画问题
[ 题目链接 ] ( h t t p s : / / w w w . l u o g u . c o m . c n / p r o b l e m / P 7771 ) [题目链接](https://www.luogu.com.cn/problem/P7771) [题目链接](https://www.luogu.com.cn/problem/P7771)
这是一道模板题 这是一道模板题 这是一道模板题
能否构成欧拉回路要满足以下几点 \large{能否构成欧拉回路要满足以下几点} 能否构成欧拉回路要满足以下几点
有向图 \quad 有向图 有向图
1
⋅
所有点入度出度相等
\qquad1 \centerdot所有点入度出度相等
1⋅所有点入度出度相等
2
⋅
如果又不相等的点则必须有两个,一个入度
−
出度
=
1
(终点),另一个出度
−
入度
=
1
(起点)
\qquad2 \centerdot如果又不相等的点则必须有两个,一个入度 - 出度 = 1(终点),另一个出度 - 入度 = 1(起点)
2⋅如果又不相等的点则必须有两个,一个入度−出度=1(终点),另一个出度−入度=1(起点)
无向图 \quad 无向图 无向图
1
⋅
所有点恰好有偶数条边
\qquad1 \centerdot所有点恰好有偶数条边
1⋅所有点恰好有偶数条边
2
⋅
有且仅有
2
个点有奇数条边(一个为起点一个为终点)
\qquad2 \centerdot有且仅有2个点有奇数条边(一个为起点一个为终点)
2⋅有且仅有2个点有奇数条边(一个为起点一个为终点)
在上述
1
的情况下,以任意一点为起点,则可以不重复的走遍所有路径回到该点
在上述1的情况下,以任意一点为起点,则可以不重复的走遍所有路径回到该点
在上述1的情况下,以任意一点为起点,则可以不重复的走遍所有路径回到该点
下面给出两种不同存图方式的代码 下面给出两种不同存图方式的代码 下面给出两种不同存图方式的代码
邻接矩阵 \small \textbf{邻接矩阵} 邻接矩阵
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int map[510][510];
int n = 1,m;
int ans = 0;
int f[1025],num[510];
void Euler(int now){
for(int i = 1; i <= n; i ++)
if(map[now][i] != 0){
map[now][i] --;
map[i][now] --;
Euler(i);
}
f[++ ans] = now;
}
int main(){
cin>>m;
memset(map,0,sizeof(map));
memset(num,0,sizeof(num));
for(int i = 1; i <= m; i ++){
int u,v;
cin>>u>>v;
n = max(n,u);
n = max(n,v);
map[u][v] ++;
map[v][u] ++;
num[u] ++;
num[v] --;
}
int s = 1;
for(int i = 1; i <= n; i ++)
if(num[i] % 2){
s = i;
break;
}
Euler(s);
for(int i = m + 1; i >= 1; i --)
cout<<f[i]<<endl;
return 0;
}
邻接链表 \small \textbf{邻接链表} 邻接链表
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
const int MAX = 100010;
int n,m,u,v,del[MAX];
int num[MAX];
stack<int> st;
vector<int> map[MAX];
void Euler(int now){
for(int i = del[now]; i < map[now].size(); i = del[now]){
del[now] = i + 1;
Euler(map[now][i]);
}
st.push(now);
}
int main(){
cin>>n>>m;
for(int i = 1; i <= m; i ++){
int u,v;
cin>>u>>v;
map[u].push_back(v);
num[u] ++;
num[v] --;
}
for(int i = 1; i <= n; i ++) sort(map[i].begin(),map[i].end());
int s = 1,cnt[2] = {0,0};
bool flag = 1;
for(int i = 1; i <= n; i ++){
if(num[i] != 0) flag = 0;
if(num[i] == 1) cnt[1] ++,s = i;
if(num[i] == -1) cnt[0] ++;
}
if((!flag)&&!(cnt[0]==cnt[1]&&cnt[0]==1)) return !printf("No");
Euler(s);
while(!st.empty()){
cout<<st.top()<<" ";
st.pop();
}
return 0;
}