题解:本题主要考查基环树+搜索。
简要题意:
n
n
n个城市之间有
m
m
m条双向道路,小Y每到达一个新的城市(包括起点)时,将它的编号记录下来。形成一个长度为
n
n
n的序列。求这个序列的字典序最小。
对于
100
%
100\%
100%的数据和所有样例,
1
≤
n
≤
5000
1≤n≤5000
1≤n≤5000且
m
=
n
−
1
m=n−1
m=n−1或
m
=
n
m=n
m=n。
1.对于
60
%
60\%
60%的数据:我们注意到
m
=
n
−
1
m=n-1
m=n−1,也就是说这是棵树。那我们可以每次都挑选编号较小的子树进行遍历即可。
代码如下:
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
vector<int> g[666666];
int v[666666],ans[666666];
int n,m,P,num;
void dfs(int p,int fa)
{
if(v[p])return ;
ans[++num]=p;
v[p]=1;
for(int i=0;i<g[p].size();i++)
{
int k=g[p][i];
if(k==fa)continue;
dfs(k,p);
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int x,y;
cin>>x>>y;
g[x].push_back(y);
g[y].push_back(x);
}
for(int i=1;i<=n;i++)
sort(g[i].begin(),g[i].end());
dfs(1,0);
for(int i=1;i<=num;i++)
cout<<ans[i]<<" ";
return 0;
}
2.对于
100
%
100\%
100%的数据:
m
=
n
m=n
m=n是一棵基环树,对于基环树,决策的难点在于环上的部分。我们就删边+DFS,即可。
代码如下:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int>g[666666];
struct edge
{
int u,to,start;
}e[666666];
int head[666666],vis[666666],ans[666666],k[666666];
int n,m,num,x,y,P;
int read()
{
int flag=1,sum=0;
char c;
scanf("%c",&c);
while (c<'0'||c>'9')
{
if(c=='-')flag=-1;
scanf("%c",&c);
}
while (c>='0'&&c<='9')
{
sum=sum*10+c-'0';
scanf("%c",&c);
}
return sum*flag;
}
void add(int start,int to)
{
e[++P].u=start;
e[P].to=to;
e[P].start=head[start];
head[start]=P;
}
void dfs(int p,int fa)
{
if(vis[p])return;
vis[p]=1;
k[++num]=p;
for(int i=0;i<g[p].size();i++)
{
int k=g[p][i];
if(k==fa)continue;
if((k==y&&p==x)||(k==x&&p==y))continue;
dfs(k,p);
}
}
bool check()
{
for(int i=1;i<=n;i++)
{
if(k[i]==ans[i])continue;
if(k[i]>ans[i])return 0;
else return 1;
}
}
void change()
{
for(int i=1;i<=n;i++)ans[i]=k[i];
}
void dfs2(int p,int fa)
{
if(vis[p])return;
vis[p]=1;
ans[++num]=p;
for(int i=0;i<g[p].size();i++)
{
int k=g[p][i];
if(k==fa)continue;
dfs2(k,p);
}
}
int main()
{
n=read();m=read();
for(int i=1;i<=m;i++)
{
int u,v;
u=read();v=read();
g[u].push_back(v);
g[v].push_back(u);
add(u,v);add(v,u);
}
for(int i=1;i<=n;i++)
sort(g[i].begin(),g[i].end());
if(n==m)
{
for(int i=0;i<P;i+=2)
{
num=0;x=e[i].u;y=e[i].to;
memset(vis,0,sizeof(vis));
dfs(1,0);
if(num<n)continue;
if(ans[1]==0)change();
else if(check())change();
}
for(int i=1;i<=n;i++)printf("%d ",ans[i]);
return 0;
}
dfs2(1,0);
for(int i=1;i<=n;i++)printf("%d ",ans[i]);
return 0;
}