我是靠谱客的博主 健康滑板,这篇文章主要介绍题解:NOIP2018旅行,现在分享给大家,希望可以做个参考。

这个题目其实挺水的,CCF数据也比较水

我们考虑对于一棵树的情况,找 dfs 序最小,那么直接贪心,从1开始找,每次遍历最小,输出即可

对于环基树,我们采用暴力断边(n<=5000),所以N2是没有任何问题的,然后更新最小字典序即可

(这个数据范围水到我连领接表都懒得开,然而本蒟蒻考场上依旧没A)

代码如下:

#include <iostream>
#include <cstring>
using namespace std; 
const int N=5050;
int x[N],y[N],a[N][N],vis[N],c[N],n,m,top;
namespace SP1 {
	void dfs(int u) {
		c[++top]=u;
		vis[u]=1;
		for(int i=1;i<=n;++i)
			if(a[u][i]&&!vis[i])
				dfs(i);
	}
	int main() {
		for(int i=1;i<=m;++i) {
			int u,v;
			cin>>u>>v;
			a[u][v]=a[v][u]=1;
		}
		dfs(1);
		for(int i=1;i<=n;++i)
			cout<<c[i]<<" ";
		return 0;
	}
}
namespace SP2 {
	int flag=0;
	bool dfs(int u) {
		if(!flag) {
			if(u>c[top+1]) return 0;
			if(u<c[top+1]) flag=1;
		}
		c[++top]=u;
		vis[u]=1;
		for(int i=1;i<=n;++i)
			if(a[u][i]&&!vis[i])
				if(!dfs(i))
					return 0;
		return 1;
	}
	int main() {
		for(int i=1;i<=n;++i) {
			c[i]=5555;
			cin>>x[i]>>y[i];
			a[x[i]][y[i]]=a[y[i]][x[i]]=1;
		}
		for(int i=1;i<=m;++i) {
			memset(vis,0,sizeof(vis));
			flag=top=0;
			a[x[i]][y[i]]=a[y[i]][x[i]]=0;
			dfs(1);
			a[x[i]][y[i]]=a[y[i]][x[i]]=1;
		}
		for(int i=1;i<=n;++i)
			cout<<c[i]<<" ";
		return 0;
	}
}
int main() {

	cin>>n>>m;
	if(m==n-1) SP1::main();
	else SP2::main();
	
	return 0;
}

最后

以上就是健康滑板最近收集整理的关于题解:NOIP2018旅行的全部内容,更多相关题解内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(134)

评论列表共有 0 条评论

立即
投稿
返回
顶部