版权声明:虽然我只是个小蒟蒻但转载也请注明出处哦 https://blog.csdn.net/weixin_42557561/article/details/83480395
Experience
突然发现欧拉回路真的是个简单的东西(之前初学的时候写的模板题,操作有点点多,所以一直有种模糊的印象好像很难的样子,但是好像也没有那么难,就是不停地dfs,然后回来的时候记录一下)
对于这道题,卡在了如何保证最后输出的是500进制下最小的那一个
后面%%“借鉴”了一下题解%%,嗯,发现只用保证每次dfs的时候是先搜的编号最小的就可以了
Analysis
我们先将边读入进来,然后根据我们的需要,将编号最小的边最后放(要理解邻接表的存储方式,就明白为什么了)
这样为什么就正确了呢?因为我们是在返回的时候才记录下点的编号,那最先访问的就是被放在最后的,然后答案是倒序输出,那最小的就是最先出来的了,这样就可以保证我们得到的是最小的那一组情况了
Code
#include<bits/stdc++.h>
#define in read()
#define M 4000
#define N 505
using namespace std;
inline int read(){
char ch;int f=1,res=0;
while((ch=getchar())<'0'||ch>'9') if(ch=='-') f=-1;
while(ch>='0'&&ch<='9'){
res=(res<<3)+(res<<1)+ch-'0';
ch=getchar();
}
return f==1?res:-res;
}
int m,S=505,g[N][N],du[N];
int nxt[M],head[N],to[M],ecnt=1;
bool vis[M];
int stk[M],top=0;
inline void add(int x,int y){
nxt[++ecnt]=head[x];head[x]=ecnt;to[ecnt]=y;
}
void dfs(int x){
for(int &e=head[x];e;e=nxt[e]){
if(!vis[e]){
vis[e]=vis[e^1]=1;
dfs(to[e]);
}
}
stk[++top]=x;
}
int main(){
m=in;
for(int i=1;i<=m;++i){
int u=in,v=in;
if(u>v) swap(u,v);
g[u][v]++;
du[u]++;du[v]++;
S=(S<u)?S:u;//万一没有奇点,是欧拉回路,则从最小的点开始
}
for(int i=500;i>=1;--i) if(du[i]&1) S=i;
for(int i=500;i>=1;--i)//循环从大到小,保证后面dfs的时候head[u]指向最小编号的点
for(int j=500;j>=1;--j){
while(g[i][j]--) add(i,j),add(j,i);
}
dfs(S);
for(int i=top;i>=1;--i) printf("%d\n",stk[i]);
return 0;
}