题目描述
小 Y 是一个爱好旅行的 OIer。她来到 X 国,打算将各个城市都玩一遍。
小Y了解到, X国的 n 个城市之间有 m 条双向道路。每条双向道路连接两个城市。 不存在两条连接同一对城市的道路,也不存在一条连接一个城市和它本身的道路。并且, 从任意一个城市出发,通过这些道路都可以到达任意一个其他城市。小 Y 只能通过这些 道路从一个城市前往另一个城市。
小 Y 的旅行方案是这样的:任意选定一个城市作为起点,然后从起点开始,每次可 以选择一条与当前城市相连的道路,走向一个没有去过的城市,或者沿着第一次访问该 城市时经过的道路后退到上一个城市。当小 Y 回到起点时,她可以选择结束这次旅行或 继续旅行。需要注意的是,小 Y 要求在旅行方案中,每个城市都被访问到。
为了让自己的旅行更有意义,小 Y 决定在每到达一个新的城市(包括起点)时,将 它的编号记录下来。她知道这样会形成一个长度为 n 的序列。她希望这个序列的字典序 最小,你能帮帮她吗? 对于两个长度均为 n 的序列 A 和 B,当且仅当存在一个正整数 x,满足以下条件时, 我们说序列 A 的字典序小于 B。
对于任意正整数1≤i
输入格式
输入文件共 m+1 行。第一行包含两个整数 n,m(m≤n),中间用一个空格分隔。
接下来 m 行,每行包含两个整数 u,v(1≤u,v≤n) ,表示编号为 u 和 v 的城市之 间有一条道路,两个整数之间用一个空格分隔。
输出格式
输出文件包含一行,n 个整数,表示字典序最小的序列。相邻两个整数之间用一个 空格分隔。
输入输出样例
输入 #1
6 5
1 3
2 3
2 5
3 4
4 6
输出 #1
1 3 2 5 4 6
输入 #2
6 6
1 3
2 3
2 5
3 4
4 5
4 6
输出 #2
1 3 2 4 5 6
说明/提示
【数据规模与约定】
对于100% 的数据和所有样例, 1≤n≤5000 且 m=n−1 或 m=n 。
对于不同的测试点, 我们约定数据的规模如下:
AC代码
#include
#include
#include
#include
#define si 5050
#define re register int
using namespace std;
struct edge {
int nex,fro,to;
}e[si<<1];
int n,m,d,bx,by,cnt,k[si],ans[si],head[si];
vector<int> p[si]; bool v[si];
inline int read() {
int x=0,cf=1;
char ch=getchar();
while(ch<'0'||ch>'9') {
if(ch=='-') cf=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') {
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return x*cf;
}
inline void add(int x,int y) {
e[++cnt].to=y,e[cnt].fro=x,e[cnt].nex=head[x],head[x]=cnt;
}
inline void dfs(int x,int fa) {
if(v[x]) return;
v[x]=1,k[++d]=x;
for(re i=0;i<p[x].size();i++) {
int y=p[x][i]; if(y==fa) continue;
if((x==bx&&y==by)||(y==bx&&x==by)) continue;//删边
dfs(y,x);
}
}
inline void change() {
for(re i=1;i<=n;i++) ans[i]=k[i];
}
inline bool check() {
for(re i=1;i<=n;i++) {
if(k[i]>ans[i]) return false;
else if(k[i]<ans[i]) return true;
}
}
inline void fans(int x,int fa) {
ans[++d]=x;
for(re i=0;i<p[x].size();i++) {
int y=p[x][i];
if(y==fa) continue;
fans(y,x);
}
}
int main() {
n=read(),m=read();
for(re i=1;i<=m;i++) {
int x=read(),y=read();
add(x,y),add(y,x);
p[x].push_back(y);
p[y].push_back(x);
}
for(re i=1;i<=n;i++) {
sort(p[i].begin(),p[i].end());//寻找最优解
}
if(n==m) {
for(re i=0;i<cnt;i+=2) {
memset(v,false,sizeof(v));
d=0,bx=e[i].fro,by=e[i].to;
dfs(1,-1);
if(d<n) continue;//这时候图不联通
else if(!ans[1]) change();//如果还没有解,那么直接当作一个解
else if(check()) change();
}
for(re i=1;i<=n;i++) {
printf("%d ",ans[i]);
}
return 0;
}
fans(1,-1);
for(re i=1;i<=n;i++) {
printf("%d ",ans[i]);
}
return 0;
}