Travel base ring tree + dfs order

Link : https://www.acwing.com/problem/content/536/

Analysis :
n is 5000, you can make O (n 2) O(n^2)O ( n2 )The approach.

The minimum lexicographic order is required, and you can preprocess it first, sort each layer in order, so that the nodes of each layer can be traversed from small to large.

n = m n =m n=When m is a tree, the lexicographic order in the title is dfs order, and you can directly search each level from small to large.

n = m + 1 n=m+1 n=m+At 1 o'clock, a ring is formed in this tree, which is a base ring tree.

When there is a loop, the search will be repeated. Then delete an edge each time, and then search the dfs order of the current tree after deletion. If the dfs order is found to be smaller than the saved one, it will be updated, and if it is larger, it will be pruned directly.

Code

#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;
}

Guess you like

Origin blog.csdn.net/u011612364/article/details/115269866