トラベルベースリングツリー+ dfsオーダー

リンク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;
}

おすすめ

転載: blog.csdn.net/u011612364/article/details/115269866