P5022 旅行

暴力拆掉每一条边试一下
因为拆的如果是树上的边就会不连通所以判掉就没问题(笑)
因为n<=5000所以随便暴力也没有问题(笑)

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
int u[10010],v[10010],ban,dfs_clock,cnt,n,m,ans[10010],mid[10010],idx[10010],nxt[10010],fir[10010],vis[10010];
vector<pair<int,int> > to[10010];
void addedge(int ui,int vi,int id){
	++cnt;
	u[cnt]=ui;
	v[cnt]=vi;
	idx[cnt]=id;
	nxt[cnt]=fir[ui];
	fir[ui]=cnt;
}
void dfs(int u,int f){
	++dfs_clock;
	mid[dfs_clock]=u;
	if(vis[u])
		return;
	vis[u]=true;
	for(int i=fir[u];i;i=nxt[i]){
		if(v[i]==f)
			continue;
		if(idx[i]==ban)
			continue;
		dfs(v[i],u);
	}
}
int main(){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++){
		int a,b;
		scanf("%d %d",&a,&b);
		to[a].push_back(make_pair(b,i));
		to[b].push_back(make_pair(a,i));
	}
	for(int i=1;i<=n;i++)
		sort(to[i].begin(),to[i].end());
	for(int i=1;i<=n;i++){
		for(int j=to[i].size()-1;j>=0;j--){
			addedge(i,to[i][j].first,to[i][j].second);
		}
	}
	memset(ans,0x3f,sizeof(ans));
	if(m==n)
		for(int i=1;i<=m;i++){
			for(int j=1;j<=n;j++)
				vis[j]=false;
			ban=i;	
			dfs_clock=0;
			dfs(1,0);
			if(dfs_clock<n)
				continue;
			bool f=false;
			for(int j=1;j<=n;j++){
				if(ans[j]==mid[j])
					continue;
				if(ans[j]<mid[j])
					break;
				if(ans[j]>mid[j]){
					f=true;
					break;
				}
			}
			if(f)
				for(int j=1;j<=n;j++)
					ans[j]=mid[j];
		}
	else{
		ban=-1;
		dfs_clock=0;
		dfs(1,0);
		bool f=false;
		for(int i=1;i<=n;i++){
			if(ans[i]==mid[i])
				continue;
			if(ans[i]<mid[i])
				break;
			if(ans[i]>mid[i]){
				f=true;
				break;
			}
		}
		if(f)
			for(int i=1;i<=n;i++)
				ans[i]=mid[i];
	}
	for(int i=1;i<=n;i++)
		printf("%d ",ans[i]);
	return 0;
}
posted @ 2019-11-14 21:08  dreagonm  阅读(121)  评论(0编辑  收藏  举报