P5022 旅行

题面:https://www.luogu.org/problem/P5022

本题显然是一个基环树,然后由于一个基环上n条边只会走n-1条边,所以只要枚举要删的边再求解即可。

Code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<ctime>
#include<vector>
using namespace std;
const int N=5005;
struct Node{
    int to,next;
}e[N<<2];
int head[N],cnt,n,m,u[N],v[N],visit[N],cutu,cutv,tot,now[N],ans[N];
bool vis[N];
vector<int> G[N];
int read(){
    int x=0,f=1;char ch=getchar();
    while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
    while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
void add(int u,int v){
    e[++cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
void dfs(int x){
    if(vis[x]){
		return;
	}
    vis[x]=1;
    printf("%d ",x);
    int a[N],num=0;
    for(int i=1;i<=n;i++){
		a[i]=0;
	}
    for(register int i=head[x];i!=-1;i=e[i].next){
		a[++num]=e[i].to;
	}
    sort(a+1,a+1+num);
    for(int i=1;i<=num;i++){
		dfs(a[i]);
	}
}
void solve(int x){
    if(visit[x]){
		return;
	}
    visit[x]=1;
    now[++tot]=x;
    for(register int i=0;i<G[x].size();i++){
        int y=G[x][i];
        if((y==cutv&&x==cutu)||(x==cutv&&y==cutu)){
			continue;
		}
        solve(y);
    }
}
bool check(){
    for(register int i=1;i<=n;i++){
        if(ans[i]==now[i]){
			continue;
		}
        if(ans[i]>now[i]){
			return 1;
		}
        if(ans[i]<now[i]){
			return 0;
		}
    }
}
int main(){
    memset(head,-1,sizeof(head));
    n=read();
	m=read();
    for(register int i=1;i<=m;i++){
        u[i]=read();
		v[i]=read();
        add(u[i],v[i]);
        add(v[i],u[i]);
        G[u[i]].push_back(v[i]);
        G[v[i]].push_back(u[i]);
    }
    for(register int i=1;i<=n;i++){
		sort(G[i].begin(),G[i].end());
	}
    if(m==n-1){
        dfs(1);
        return 0;
    }
    else{
        for(register int i=1;i<=m;i++){
            tot=0,cutu=u[i],cutv=v[i];
            memset(visit,0,sizeof(visit));
            solve(1);
            if(tot==n){
                if(ans[1]==0){
                    for(register int j=1;j<=n;j++){
						ans[j]=now[j];
					}
                }
                else if(check()){
                    for(register int j=1;j<=n;j++){
						ans[j]=now[j];
					}
                }
            }
        }
        for(int i=1;i<=n;i++){
			printf("%d ",ans[i]);
		}
        return 0;
    }
}
posted @ 2019-08-20 13:10  prestige  阅读(123)  评论(0编辑  收藏  举报