其实是一道简单题。
m=n-1傻子都会
m=n只要每次删一条边再处理就可以了。注意一些限制条件。
#include<bits/stdc++.h>
using namespace std;
const int N=5005;
int n,m,ans[N],cnt,x[N],y[N],Head[N*2],a[N];
int head[N*2],tot=0,flag[N],tem[N],Tot=0;
inline int read()
{
int x=0,f=1;char s=getchar();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
return x*f;
}
struct node
{
int vet,nxt;
}edge[N*2],Edge[N*2];
void Add(int u,int v)
{
Edge[++Tot].vet=v;
Edge[Tot].nxt=Head[u];
Head[u]=Tot;
}
void add(int u,int v)
{
edge[++tot].vet=v;
edge[tot].nxt=head[u];
head[u]=tot;
}
void dfs(int u,int fa)
{
ans[++cnt]=u;
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].vet;
if(v!=fa)dfs(v,u);
}
}
void Dfs(int u,int fa)
{
tem[++cnt]=u;
if(cnt>n)return;
for(int i=head[u];i;i=edge[i].nxt)
{
if(cnt>n)return;
int v=edge[i].vet;
if(v!=fa&&(!flag[u]||!flag[v]))Dfs(v,u);
}
}
void check()
{
memset(tem,0,sizeof(tem));
cnt=0;Dfs(1,0);
if(cnt>n)return;
bool Flag=0;
for(int i=1;i<=n;i++)
if(tem[i]==0)return;
for(int i=1;i<=n;i++)
if(tem[i]<ans[i])
{
Flag=1;break;
}else if(tem[i]>ans[i])return;
if(Flag)
for(int i=1;i<=n;i++)ans[i]=tem[i];
}
int main()
{
n=read(),m=read();
for(int i=1;i<=m;i++)
{
x[i]=read(),y[i]=read();
Add(x[i],y[i]);Add(y[i],x[i]);
}
for(int u=1;u<=n;u++)
{
cnt=0;
for(int i=Head[u];i;i=Edge[i].nxt)
a[++cnt]=Edge[i].vet;
sort(a+1,a+cnt+1);
for(int i=cnt;i>=1;i--)add(u,a[i]);
}
if(n>m)
{
cnt=0;dfs(1,0);
for(int i=1;i<n;i++)printf("%d ",ans[i]);
printf("%d\n",ans[n]);
}else
{
memset(flag,0,sizeof(flag));
memset(ans,0x3f,sizeof(ans));
for(int i=1;i<=m;i++)
{
flag[x[i]]=flag[y[i]]=1;
check();
flag[x[i]]=flag[y[i]]=0;
}
for(int i=1;i<n;i++)printf("%d ",ans[i]);
printf("%d\n",ans[n]);
}
return 0;
}