题意:求给定图像的最大独立点集,并给出一组点集
思路:即求其补图的最大团。求最大团方法:对顶点进行深搜,并用分支限界策略剪枝。
输入:
1
6 8
1 2
1 3
2 4
2 5
3 4
3 6
4 6
5 6
输出:
3
1 4 5
#include <stdio.h>
#include <string.h>
#define N 102
int map[N][N],res[N],used[N];
int best_num,now_num;
int n,m,T;
void dfs(int x){
int i,flag = 1;
if(x == n+1){
if(now_num > best_num){
best_num = now_num;
for(i = 1;i<=n;i++)
res[i] = used[i];
}
return ;
}
for(i = 1;i<x;i++)
if(used[i] && !map[i][x]){
flag = 0;
break;
}
if(flag){
used[x] = 1;
now_num++;
dfs(x+1);
used[x] = 0;
now_num--;
}
if(now_num+n-x>best_num)//剪枝,如果剩下的点全部组成团还没有best多,则不必再搜
dfs(x+1);
}
int main(){
freopen("a.txt","r",stdin);
scanf("%d",&T);
while(T--){
int i,j;
memset(map,0,sizeof(map));
memset(used,0,sizeof(used));
memset(res,0,sizeof(res));
best_num = now_num = 0;
scanf("%d %d",&n,&m);
while(m--){
scanf("%d %d",&i,&j);
map[i][j] = map[j][i] = 1;
}
for(i = 1;i<=n;i++)
for(j = 1;j<=n;j++)
map[i][j] = 1-map[i][j];
dfs(1);
printf("%d\n",best_num);
for(i = 1;i<=n;i++)
if(res[i])
printf("%d ",i);
printf("\n");
}
return 0;
}