【JZOJ5964】【NOIP2018】旅行
程序员文章站
2024-03-20 11:12:28
...
description
小Y是一个爱好旅行的OIer。她来到X国,打算将各个城市都玩一遍。
小Y了解到,X国的n个城市之间有m条双向道路。每条双向道路连接两个城市。不存在两条连接同一对城市的道路,也不存在一条连接一个城市和它本身的道路。并且,从任意一个城市出发,通过这些道路都可以到达任意一个其他城市。小Y只能通过这些道路从一个城市前往另一个城市。
小Y的旅行方案是这样的:任意选定一个城市作为起点,然后从起点开始,每次可以选择一条与当前城市相连的道路,走向一个没有去过的城市,或者沿着第一次访问该城市时经过的道路后退到上一个城市。当小Y回到起点时,她可以选择结束这次旅行或继续旅行。需要注意的是,小Y要求在旅行方案中,每个城市都被访问到。
为了让自己的旅行更有意义,小Y决定在每到达一个新的城市(包括起点)时,将它的编号记录下来。她知道这样会形成一个长度为n的序列。她希望这个序列的字典序最小,你能帮帮她吗?
对于两个长度均为n的序列A和B,当且仅当存在一个正整数x,满足以下条件时,我们说序列A的字典序小于B。
①对于任意正整数1<=i<x,序列A的第i 个元素Ai 和序列B的第i 个元素Bi相同。
②序列A的第x个元素的值小于序列B的第x个元素的值。
analysis
-
从号点走出序就行了
-
的话枚举哪一条树边不能走
-
暴力不能接受,但是可以先排序预处理,均摊不超
-
于是记录最小字典序的答案即可
code
#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 5005
#define fo(i,a,b) for (int i=a;i<=b;++i)
#define fd(i,a,b) for (int i=a;i>=b;--i)
#define rep(i,a) for (int i=last[a];i;i=next[i])
#define O3 __attribute__((optimize("-O3")))
using namespace std;
int f[MAXN][MAXN],gx[MAXN],gy[MAXN],ans[MAXN],answer[MAXN];
bool b[MAXN][MAXN],bz[MAXN];
int n,m,tot,pos;
O3 inline int max(int x,int y)
{
return x>y?x:y;
}
O3 inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
O3 inline void dfs(int x)
{
printf("%d ",x),bz[x]=0;
fo(i,1,n)if (b[x][i] && bz[i])dfs(i);
}
O3 inline void dfs1(int x)
{
ans[++pos]=x,bz[x]=0;
fo(i,1,f[x][0])if (b[x][f[x][i]] && bz[f[x][i]])dfs1(f[x][i]);
}
O3 inline bool judge()
{
fo(i,1,n)
{
if (ans[i]<answer[i])return 1;
else if (ans[i]>answer[i])return 0;
}
return 0;
}
O3 int main()
{
freopen("travel.in","r",stdin);
freopen("travel.out","w",stdout);
n=read(),m=read();
fo(i,1,m)
{
int x=read(),y=read();
gx[i]=x,gy[i]=y;
b[x][y]=b[y][x]=1;
f[x][++f[x][0]]=y,f[y][++f[y][0]]=x;
}
if (n==m+1)
{
memset(bz,1,sizeof(bz));
dfs(1);
printf("\n");
return 0;
}
fo(i,1,n)sort(f[i]+1,f[i]+f[i][0]+1),answer[i]=1000000007;
fo(i,1,m)
{
memset(bz,1,sizeof(bz));
int x=gx[i],y=gy[i];
b[x][y]=b[y][x]=pos=0;
dfs1(1);
if (judge())memcpy(answer,ans,sizeof(answer));
b[x][y]=b[y][x]=1;
}
fo(i,1,n)printf("%d ",answer[i]);
printf("\n");
return 0;
}
上一篇: 1.9会话跟踪——Session技术