LGOJ5022 旅行 noip tg 2018

Posted yangxuejian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LGOJ5022 旅行 noip tg 2018相关的知识,希望对你有一定的参考价值。

旅行

标签(空格分隔): noip2018 提高组


今天我给大家带来一份题解。
题目的大大致意思是这样的:

\[ 有一颗 树/基环树 求最小遍历顺序 \]

树的情况自然不必多讲。做一些末端的微处理(将每个点的邻接点排序)即可。
而基环树呢?这是我们就要普及一下基环树的知识了。
\[ 基环树,简单来讲,就是在一棵树上连一条边,构成一个环。\]
SO
如何处理??
来,边看代码边讲!

#include<bits/stdc++.h>
using namespace std; 
const int maxn = 5e3+5;
int n,m,x,y,dep; 
vector <int> e[maxn]; //ling'jie'biao'cun'bian
int tmp[maxn],ans[maxn],cnt,rd[maxn];
bool Tre[maxn],vis[maxn],done[maxn][maxn];
struct edge
    int x,y;
del;
void dfs(int pos)
    if(dep>n)return;
    tmp[dep]=pos;vis[pos]=1;
    for(int i=0;i<e[pos].size();i++)
        int next=e[pos][i];
        if((del.x == pos && del.y == next) || (del.x == next && del.y == pos))
            continue;
        if(!vis[next])
            vis[next]=1;
            dep++;
            dfs(next);
        
    

void top()
    queue<int>q;
    for(int i=1;i<=n;i++)
        if(rd[i]==1)
            Tre[i]=1;
            rd[i]--;
            q.push(i);
        
    
    while(!q.empty())
        int x=q.front();q.pop();
        Tre[x]=1;
        for(int j=0;j<e[x].size();j++)
            int y=e[x][j];
            rd[y]--;
            if(rd[y]==1)
                q.push(y);
            
        
    
    return ;

bool check()
    for(int i=1;i<=n;i++)
        if(ans[i] == tmp[i])
            continue;
        
        if(ans[i] < tmp[i])
            return false;
        
        if(ans[i] > tmp[i])
            return true;
           
    

void update()
    if(ans[1]==0)
        for(int i=1;i<=n;i++)
            ans[i]=tmp[i];
        
    
    else if(check())
        for(int i=1;i<=n;i++)
            ans[i]=tmp[i];
        
    

void out()
    for(int i=1;i<=n;i++)
        printf("%d ",ans[i]);
    
    return ;

int main()
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
        scanf("%d%d",&x,&y);
        e[x].push_back(y);rd[y]++; 
        e[y].push_back(x);rd[x]++;
    
    for(int i=1;i<=n;i++)
        sort(e[i].begin(),e[i].end());
    
    if(m == n-1)
        dep = 1;
        Tre[1]=true;
        dfs(1);
        update();
    
    else 
        top();
        for(int i=1;i<=n;i++)
            if(!Tre[i])
                for(int j=0;j<e[i].size();j++)
                    if(!Tre[e[i][j]])
                        del.x = i;
                        del.y = e[i][j];
                        if(done[del.x][del.y])
                            continue;
                        
                        done[del.x][del.y]=done[del.y][del.x]=1;
                        memset(vis,0,sizeof(vis));
                        vis[1]=true;dep=1;dfs(1);
                        update(); 
                    
                
            
         
    
    out();
    return 0;

以上是关于LGOJ5022 旅行 noip tg 2018的主要内容,如果未能解决你的问题,请参考以下文章

NOIP_1999.TG4:邮票面值设计

题解 P5022 旅行

P5022 旅行

NOIP2011tg

题解 P1453 城市环路

NOIP TG 2014 寻找道路