迭代加深搜索。
考虑对于一次操作,操作的这个点和与它相连的点构成一个完全联通块。
那么用并查集维护每个点属于哪个块,块的大小。
由于一次操作后,与它相连的点一定也会操作。
所以操作完一个点,就去操作与它相连的点。
#include<bits/stdc++.h>
using namespace std;
const int N=30;
int n,m,sizee[N],ans[N],b[N],linkk[N],t,f[N];
struct hzy{int next,val;}e[N*N];
void ling(int x,int y){
e[++t].val=y;
e[t].next=linkk[x];
linkk[x]=t;
}
int zuxian(int k){return f[k]==k?k:f[k]=zuxian(f[k]);}//并查集
bool dfs(int now,int s,int dep){
if(sizee[zuxian(now)]==n)return 1;//所有点都是一个块
if(s>=dep)return 0;
b[now]=1;
ans[s+1]=now;
for(int i=linkk[now];i;i=e[i].next){//合并
int y=e[i].val;
int x1=zuxian(y);
int x2=zuxian(now);
if(x1==x2)continue;
f[x2]=x1;
sizee[x1]+=sizee[x2];
sizee[x2]=0;
}
for(int i=linkk[now];i;i=e[i].next){
int y=e[i].val,si[N],fa[N];
memcpy(si,sizee,sizeof(sizee));//存储状态
memcpy(fa,f,sizeof(f));
if(b[y]==0)if(dfs(y,s+1,dep))return 1;
memcpy(sizee,si,sizeof(si));
memcpy(f,fa,sizeof(fa));
}
return 0;
}
void clear(){//清空
memset(b,0,sizeof(b));
for(int i=1;i<=n;i++)f[i]=i,sizee[i]=1;
}
int main(){
scanf("%d%d",&n,&m);
if(m==n*(n-1)/2){
puts("0");
return 0;
}
for(int i=1;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
ling(x,y);
ling(y,x);
}
for(int dep=1;dep<=n;dep++){
for(int st=1;st<=n;st++){
clear();
if(dfs(st,0,dep)){
printf("%d\n",dep);
for(int i=1;i<=dep;i++)printf("%d ",ans[i]);
return 0;
}
}
}
}
hack:
答案应该是4(2 3 7 4 ),你的程序输出6
大佬Orz
zuxian就离谱啊