LGP5049题解
作者:互联网
无内鬼,来个线性做法
发现是一个 sb 贪心,只需要保证下一个去的节点尽量小即可。
问题分为三个阶段:在一颗“子树”内,在环上,在别的“子树”内。(环上每个节点挂着一堆子树)
首先肯定从 \(1\) 开始搜。尽量走小的地方。
走到环上后需要决定走哪个方向,这个很容易。
在环上某个位置需要判定是否停下来,判断一下如果不向前走的话,序列的下一个位置会是多少即可。
然后细节差不多就是这些了。。。在别的子树内很容易实现。
但是需要对节点排序,挂在 vector 上然后扫一遍往回插入即可。
#include<algorithm>
#include<cstdio>
#include<vector>
const int M=5e5+5;
int n,m,f[M];std::vector<int>G[M],id[M];bool vis[M],inr[M];int top,stk[M];
int x[M],y[M];
inline int min(const int&a,const int&b){
return a>b?b:a;
}
inline void SolveTree(const int&u){
printf("%d ",u);
vis[u]=true;for(int&v:G[u])if(!vis[v])SolveTree(v);
}
inline void SolveRing(const int&u,const int&V,const bool&typ){
printf("%d ",u);
vis[u]=true;
for(int v,i=0;i<G[u].size();++i)if(!vis[v=G[u][i]]){
if(inr[v]&&(typ||v<V||(i+1==G[u].size()?false:i+1+vis[G[u][i+1]]!=G[u].size()))){
SolveRing(v,i+1==G[u].size()?V:vis[G[u][i+1]]?i+2==G[u].size()?V:G[u][i+2]:G[u][i+1],typ);
}
if(!inr[v])SolveTree(v);
}
}
inline void SolveBegin(const int&u){
printf("%d ",u);
vis[u]=true;
if(inr[u]){
bool typ(false);
for(int v,i=0;i<G[u].size();++i)if(!vis[v=G[u][i]]){
if(inr[v])SolveRing(v,typ?n+1:G[u][i+1],typ),typ=true;
else SolveBegin(v);
}
}
else for(int&v:G[u])if(!vis[v])SolveBegin(v);
}
inline bool FindRing(const int&u){
stk[++top]=u;
for(int&v:G[u])if(v^f[u]){
if(f[v]){
do inr[stk[top]]=true;while(stk[top--]^v);return f[u]=0,true;
}
f[v]=u;if(FindRing(v))return f[u]=0,true;
}
return --top,f[u]=0,false;
}
signed main(){
scanf("%d%d",&n,&m);
for(int u,v,i=1;i<=m;++i)scanf("%d%d",&u,&v),id[v].push_back(u),id[u].push_back(v);
for(int u=1;u<=n;++u)for(int&v:id[u])G[v].push_back(u);FindRing(1);SolveBegin(1);
}
标签:LGP5049,const,环上,int,题解,vis,inline,include 来源: https://www.cnblogs.com/lmpp/p/16106185.html