旅行sol

旅行

  • 考虑树上因为不能回溯,贪心即可
  • 基环树暴力删边后变成树再遍历一遍,复杂度(O(n^2))
  • 更快的做法还不会。。。
#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define SZ(x) ((int)x.size())
#define ALL(x) x.begin(),x.end()
#define U(i,u) for(register int i=head[u];i;i=nxt[i])
#define rep(i,a,b) for(register int i=(a);i<=(b);++i)
#define per(i,a,b) for(register int i=(a);i>=(b);--i)
using namespace std;
typedef long double ld;
typedef long long ll;
typedef unsigned int ui;
typedef pair<int,int> PII;
typedef vector<int> VI;
template<class T> inline void read(T &x){
	x=0;char c=getchar();int f=1;
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=x*10+c-'0';c=getchar();}x*=f;
}
template<class T> inline void cmin(T &x, T y){x=x<y?x:y;}
template<class T> inline void cmax(T &x, T y){x=x>y?x:y;}
const int N=500010;
int n,m,head[N],nxt[N],v[N],cnt;
int num[N],amt,ans[N];
int used[N];
int uu,vv;
VI so[N];
void add(int x,int y){
	nxt[++cnt]=head[x];head[x]=cnt;v[cnt]=y;
	so[x].pb(y);
}
void dfs(int now){
	num[++amt]=now;
	used[now]=1;
	if(SZ(so[now])){
		for(int i=0;i<SZ(so[now]);i++){
			if(used[so[now][i]])continue;
			if((now==uu&&so[now][i]==vv)||(now==vv&&so[now][i]==uu))continue;
			dfs(so[now][i]);
		}
	}
}
void check(){
	if(ans[1]==0){
		rep(i,1,n)ans[i]=num[i];
		return;
	}
	rep(i,1,n){
		if(ans[i]==num[i])continue;
		if(ans[i]>num[i]){
			rep(j,i,n)ans[j]=num[j];
			return;
		}else return;
	}
}
int main(){
	read(n);read(m);
	rep(i,1,m){int a,b;read(a);read(b);add(a,b);add(b,a);}
	rep(i,1,n)sort(ALL(so[i]));
	if(m==n){
		rep(i,1,m){
			rep(i,1,n)used[i]=0;
			uu=v[i*2-1];vv=v[i*2];amt=0;dfs(1);
			if(amt==n)check();
		}
		rep(i,1,n){
			printf("%d ",ans[i]);
		}
	}else{
		rep(i,1,n)used[i]=0;
		amt=0;
		dfs(1);
		rep(i,1,n)printf("%d ",num[i]);
	}
	
	return 0;
}
原文地址:https://www.cnblogs.com/hangzz/p/13405587.html