P5049 【旅行(数据加强版)】

· · 题解

P5049 旅行(数据加强版)

这题目真的是细节超多,乍一看感觉挺简单,其实想要AC并不容易

大概就是这么多啦,下面再贴一份AC代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
const int N=5e5+5;
int n,m;
int dfn[N],low[N],vis[N];
int loop[N],bottom,mn=0x3f3f3f3f;
bool looped,already;
int kk;
vector<int>e[N];
stack<int>s;
bool cmp(int x,int y)
{
    return x<y;
}
void tarjan(int x,int from,int cnt)
{
    dfn[x]=cnt;
    low[x]=cnt;
    s.push(x);
    vis[x]=1;
    for(int i=0;i<e[x].size();i++)
    {
        int to=e[x][i];
        if(to==from)continue;
        if(vis[to]==1)
        {
            low[x]=min(low[x],dfn[to]);
            looped=1;
            bottom=to;
        }
        else 
        {
            tarjan(to,x,cnt+1);
            low[x]=min(low[to],low[x]);
        }
        if(looped==1)return;
    }
    if(dfn[x]==low[x])
    {
        s.pop();
        vis[x]=0;
    }
}
void get_loop()
{
    int x;
    while(x!=bottom&&s.empty()!=1)
    {
        x=s.top();
        s.pop();
        loop[x]=1;
    }
    loop[bottom]=1;
}
//以下是核心部分********
void dfs(int x,int from)
{
    bool in_loop=loop[x];
    cout<<x<<" ";
    vis[x]=1;
    if(in_loop==0||already==1)
    {
        for(int i=0;i<e[x].size();i++)
        if(vis[e[x][i]]==0)dfs(e[x][i],x);
    }
    else if(in_loop==1)
    {
        if(x==bottom)
        {
            for(int i=0;i<e[x].size();i++)
            {
                int to=e[x][i];
                if(vis[to]==1)continue;
                if(loop[to]==1)
                {
                    kk=to;
                    int tmp=i+1;
                    mn=e[x][tmp];
                    break;
                }
            }
        }
        for(int i=0;i<e[x].size();i++)
        {
            int to=e[x][i];
            if(vis[to]==1)continue;
            if(already==0&&mn<to&&loop[to]==1&&(i+1==e[x].size()||(i+2==e[x].size()&&e[x][i+1]==from)))
            {
                int to=mn;
                already=1;
                dfs(to,x);
            }
            else if(already==1)
                dfs(to,x);
            else if(loop[to]==1)
            {
                int tmp=i+1;
                    while(vis[e[x][tmp]]==1)tmp++;
                    if(e[x][tmp]!=0)mn=e[x][tmp];
                dfs(to,x);
            }
            else dfs(to,x);
        }
    }
}
//以上是核心部分********
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        e[u].push_back(v);
        e[v].push_back(u);
    }
    for(int i=1;i<=n;i++)sort(e[i].begin(),e[i].end(),cmp);
    tarjan(1,0,1);
    get_loop();
    memset(vis,0,sizeof(vis));
    dfs(1,1);
    return 0;
}
\text{Update}\ \ 10.28

原代码在原题中会WA一个点,更新后修复了这个bug。感谢 @HH_Halo