NOIp提高组2018 旅行————基环树+搜索

题解:本题主要考查基环树+搜索。
简要题意: n n n个城市之间有 m m m条双向道路,小Y每到达一个新的城市(包括起点)时,将它的编号记录下来。形成一个长度为 n n n的序列。求这个序列的字典序最小。
对于 100 % 100\% 100%的数据和所有样例, 1 ≤ n ≤ 5000 1≤n≤5000 1n5000 m = n − 1 m=n−1 m=n1 m = n m=n m=n
1.对于 60 % 60\% 60%的数据:我们注意到 m = n − 1 m=n-1 m=n1,也就是说这是棵树。那我们可以每次都挑选编号较小的子树进行遍历即可。
代码如下:

#include
#include
#include
#include
using namespace std;
vector 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>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<

2.对于 100 % 100\% 100%的数据: m = n m=n m=n是一棵基环树,对于基环树,决策的难点在于环上的部分。我们就删边+DFS,即可。
代码如下:

#include
#include
#include
#include
#include
using namespace std;
vectorg[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;ians[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

你可能感兴趣的:(搜索,图论)