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;
}
本文来自博客园,作者:北烛青澜,转载请注明原文链接:https://www.cnblogs.com/Multitree/articles/17796358.html
The heart is higher than the sky, and life is thinner than paper.