リンク:https://www.acwing.com/problem/content/536/
分析:
nは5000であり、O(n 2)O(n ^ 2)を作成できます。O (n2)アプローチ。
最小の辞書式順序が必要です。最初に前処理し、各レイヤーを順番に並べ替えて、各レイヤーのノードを小さいものから大きいものにトラバースできるようにします。
n = mn = m n=mがツリーの場合、タイトルの辞書式順序はdfs順序であり、各レベルを小さいものから大きいものまで直接検索できます。
n = m + 1 n = m + 1 n=m+1時に、ベースリングツリーであるこのツリーにリングが形成されます。
リングがある場合は、検索を繰り返します。毎回エッジを削除し、削除後、現在のツリーのdfs順序を検索します。dfs順序が保存されている順序よりも小さい場合は、更新されます。 、それが大きい場合は、直接剪定されます。
コード
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 5005;
#define INF 0x3f3f3f3f
struct edge
{
int u,v;
void add(int a,int b){
u = a;
v = b;
}
}e[maxn];
vector<int> g[maxn];
int ans[maxn];
int vis [maxn];
int cnt = 1;
int flag;
int del_u,del_v;
int dfs(int u,int fa){
if(!flag){
if(u > ans[cnt])
return 1;
if(u < ans[cnt])
flag = 1;
}
vis[u] = 1;
ans[cnt++] = u;
for(auto v: g[u]){
if(vis[v])
continue;
if((u == del_u && v == del_v) || (u == del_v && v == del_u))
continue;
if(dfs(v,u)) return 1;
}
return 0;
}
int main()
{
int n,m,u,v;
cin>>n>>m;
memset(ans,INF,sizeof(ans));
for(int i = 0;i < m; i++ ){
cin>>u>>v;
e[i].add(u,v);
g[u].push_back(v);
g[v].push_back(u);
}
for(int i = 1;i <= n; i++)
sort(g[i].begin(),g[i].end());
if(n - 1 ==m ){
dfs(1,0);
for(int i = 1;i <= n; i++)
cout<<ans[i]<<" ";
}
else{
for(int i = 0;i < m; i++){
memset(vis,0,sizeof(vis));
del_u = e[i].u;
del_v = e[i].v;
flag = 0;
cnt = 1;
dfs(1,0);
}
for(int i = 1;i <= n; i++)
cout<<ans[i]<<" ";
}
return 0;
}