AcWing 534. 旅行
原题链接
简单
作者:
冷丁Hacker
,
2020-05-15 21:55:30
,
所有人可见
,
阅读 784
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=5010;
int n,m;
vector<int> e[N];
PII edge[N];
int del_u,del_v;
vector<int> ans(N,N);
vector<int> path(N);
bool st[N];
int cnt,state;
bool dfs(int u){
if(!state){
//维护最优的答案 如果发现当前的大于之前的ans对应位置(因为ans的初始化都是N)
//所以如果大于了,说明现在的答案一定没有之前的好,则返回
if(u>ans[cnt]) return true;
if(u<ans[cnt]) state=-1;
}
st[u]=true;
path[cnt++]=u;
for(int i=0;i<e[u].size();i++){
int x=e[u][i];
if(!(x==del_u&&u==del_v)&&!(x==del_v&&u==del_u)&&!st[x])
//这个if的意思为如果遇到了删除的那条边则跳过
//如果当前这点已经使用过了也跳过
if(dfs(x))return true;
}
return false;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
int a,b;
scanf("%d%d",&a,&b);
e[a].push_back(b);
e[b].push_back(a);
edge[i]=make_pair(a,b);
}
for(int i=1;i<=n;i++)
sort(e[i].begin(),e[i].end());
if(n==m){ //n==m,则不再是搜索树,说明存在环形边
//这时候如果我们还要用搜索树的方法来求解,就要删除一条边
for(int i=0;i<m;i++){
//del_u和del_v 代表被删除的那条边
del_u=edge[i].first,del_v=edge[i].second;
memset(st,false,sizeof(st));
cnt=state=0;
dfs(1);
if(cnt==n)
ans=path;
}
}
else{
dfs(1);
if(cnt==n)
ans=path;
}
for(int i=0;i<n;i++)
printf("%d ",ans[i]);
return 0;
}