//https://img2018.cnblogs.com/blog/1646268/201908/1646268-20190806114008215-138720377.jpg

NOIP 2018 旅行

观察题面,有 \(m \le n\) 说明是基环树或者一棵树。

所以我们可以暴力枚举删哪一条边,然后暴力搜索即可。

考虑用 vector 存图,把每一个点与之相连的点的编号从小到大排序,这样从一号点开始搜索得到的 DFS 序一定是字典序最小的。

如果要是 \(m=n-1\) 的话,直接从一号点 DFS 一遍就是答案了。

其中如果要是最后实际遍历到的点数量小于 \(n\) 个,说明此时图不连通,不统计答案。

/*
 * @Author: Aisaka_Taiga
 * @Date: 2023-10-29 19:40:37
 * @LastEditTime: 2023-10-29 20:07:36
 * @LastEditors: Aisaka_Taiga
 * @FilePath: \Desktop\P5022.cpp
 * The heart is higher than the sky, and life is thinner than paper.
 */
#include <bits/stdc++.h>

#define int long long
#define N 5100

using namespace std;

inline int read()
{
    int x = 0, f = 1;
    char c = getchar();
    while(c < '0' || c > '9'){if(c == '-') f = -1; c = getchar();}
    while(c <= '9' && c >= '0') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return x * f;
}

int n, m, ans[N], k[N], top, vis[N], cnt, head[N], X, Y, U[N], V[N];
vector<int> g[N];

inline void change()
{
    for(int i = 1; i <= n; i ++) ans[i] = k[i];
    return ;
}

inline void dfs1(int u, int fa)
{
    if(vis[u]) return ;
    vis[u] = 1;
    k[++ top] = u;
    for(auto v : g[u])
    {
        if(v == fa) continue;
        if((u == X && v == Y) || (u == Y && v == X)) continue;
        dfs1(v, u);
    }
    return ;
}

inline int check()
{
    for(int i = 1; i <= n; i ++)
    {
        if(ans[i] > k[i]) return 1;
        if(ans[i] < k[i]) return 0;
    }
    return 0;
}

inline void dfs2(int u, int fa)
{
    if(vis[u]) return ;
    vis[u] = 1;
    ans[++ top] = u;
    for(auto v : g[u])
        if(v != fa) dfs2(v, u);
    return ;
}

signed main()
{
    n = read(), m = read();
    for(int i = 1; i <= m; i ++)
    {
        U[i] = read(), V[i] = read();
        g[U[i]].emplace_back(V[i]);
        g[V[i]].emplace_back(U[i]);
    }
    for(int i = 1; i <= n; i ++)
        sort(g[i].begin(), g[i].end());
    ans[1] = 2;
    if(n == m)
    {
        for(int i = 1; i <= m; i ++)
        {
            top = 0;
            X = U[i], Y = V[i];
            memset(vis, 0, sizeof vis);
            dfs1(1, 0);
            if(top < n) continue;
            if(check()) change();
        }
    }
    else dfs2(1, 0);
    for(int i = 1; i <= n; i ++)
        cout << ans[i] << " ";
    return 0;
}
posted @ 2023-10-29 20:12  北烛青澜  阅读(4)  评论(0编辑  收藏  举报