AcWing 6053. 一笔画问题
原题链接
简单
首先要明确,欧拉路径还是欧拉回路,一定要走完所有的边,而非只是走完所有点
欧拉回路存在等价于图中的点度数均为偶数
欧拉路径存在等价于图中有且仅有两个奇数度顶点,则存在这两个顶点的欧拉路径
那对于本题而言,先判断所有点的度数,没有奇数度点就随便找一个点dfs
有奇数度点就从那点开始dfs,代码如下
C++ 代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110, M = 4010;
int h[N], e[M], ne[M], idx;
int n,m;
int degree[N]; //统计每个点的度数
int arr[M]; //记录答案
bool st[N][N]; //判断i,j连接的边是否走过
bool flag; //找到一个合法的方案就直接返回
void dfs(int u,int sum){ //u表示当前所在节点,sum表示纳入了多少条边
if (flag) return ; //找到合法方案,return
arr[sum]=u;
if (sum==m){
for(int i=0;i<=m;i++){
cout<<arr[i]<<" ";
}
cout<<endl;
flag=true;
return ;
}
for(int i=h[u];~i;i=ne[i]){ //找当前u的所有邻边
int j=e[i];
if (st[u][j]||st[j][u]) continue; //走过了不能再走
st[u][j]=true;
st[j][u]=true;
arr[++sum]=j; //方案合法就走,纳入一个点的同时,边也会加一条
dfs(j,sum);
st[u][j]=0; //恢复现场
st[j][u]=0;
sum--;
}
}
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}
int main()
{
cin>>n>>m;
memset(h, -1, sizeof h);
for(int i=1;i<=m;i++){ //加边并统计度数
int a,b;
cin>>a>>b;
add(a,b),add(b,a);
degree[a]++;
degree[b]++;
}
for(int i=1;i<=n;i++){ //按上面说的情况分类讨论
if (degree[i]%2){
dfs(i,0);
return 0;
}
}
dfs(1,0);
return 0;
}
bool st[N][N]; //判断i,j连接的边是否走过
可不可以开一维数组怎么开成一维的啊🤔
就跟树的重心一样啊(个人猜测)(本人没实力打不出来)
一般dfs是搜完所有点就行,但这个一笔画一定要把所有边走完,点可以重复经过多次,用一维状态应该是不好存的,本题因为没有重边,所以i,j两个量能唯一确定一条边
谢谢Orz