UVA_193
这个题目的题意并不难理解,但由于这个题目节点数最多可到100个,如果是直接依次枚举每个点并判断这个点时候可以涂成黑色的话是会超时的。
仔细想了一下,实际上如果一个点涂成黑色的话,那么和它相邻的所有点都必须涂成白色,这样如果我们每涂一个黑色的点,实际上剩下的可以涂成黑色的点就很明显了,只要是没有涂过色的都可以。只要按这样的规则不停地枚举可以涂成黑色的点并将其涂成黑色就可以了,当被涂色的点的数量达到n时,就可以数涂成黑色的点的数量了,或者可以直接把黑色的点的数量当做深搜函数的一个参数,这样最后就不用再数一遍了。
想到上面的思路后,深搜的函数就比较好写了。
#include<stdio.h>
#include<string.h>
int G[110][110];
int n,ans[110],res;
void dfs(int cur,int *A)
{
int i,j,num,color[110];
if(cur==n)
{
num=0;
for(i=0;i<n;i++)
if(A[i])
num++;
if(num>res)
{
memcpy(ans,A,sizeof(ans));
res=num;
}
return;
}
for(i=0;i<n;i++)
if(A[i]<0)
{
memcpy(color,A,sizeof(color));
color[i]=1;
num=1;
for(j=0;j<n;j++)
if(G[i][j]&&color[j]<0)
{
color[j]=0;
num++;
}
dfs(cur+num,color);
}
}
int main()
{
int i,j,k,t,m,a,b,A[110];
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(G,0,sizeof(G));
for(i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
a--;
b--;
G[a][b]=G[b][a]=1;
}
res=0;
memset(A,-1,sizeof(A));
dfs(0,A);
printf("%d\n",res);
k=0;
for(i=0;i<n;i++)
if(ans[i])
{
if(k++)
printf(" ");
printf("%d",i+1);
}
printf("\n");
}
return 0;
}