1029 -欧拉回路(简单dfs) - 骑马修栅栏(USACO Training Section 3.3)

版权声明:虽然我只是个小蒟蒻但转载也请注明出处哦 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;
}

猜你喜欢

转载自blog.csdn.net/weixin_42557561/article/details/83480395
今日推荐