(1)思路:
找到一个最大的集合,其中任意两点都不想交,这就是就将最大团的限制翻转过来了(最大团是任意两点都能到大),
然后用dfs搜索一遍就好了。
(2)代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 105;
int ans,n,m,mp[maxn][maxn],num[maxn],vis[maxn];
vector <int> vc,tp;
bool dfs(int *a2,int len,int cnt,vector <int> &vv){
if(len==0){
if(cnt>ans){
ans = cnt;
vc = vv;
return true;
}
return false;
}
int tmp[maxn];
for(int i=0;i<len;i++){
if(cnt+num[a2[i]]<=ans) return false;
if(cnt+len-i<=ans) return false;
int k = 0;
for(int j=i+1;j<len;j++)
if(mp[a2[i]][a2[j]]==0) tmp[k++] = a2[j];
vv.push_back(a2[i]);
if(dfs(tmp,k,cnt+1,vv)==true)
return true;
vv.pop_back();
}
return false;
}
void fun(){
ans = 0;
int a1[maxn];
for(int i=n;i>=1;i--){
int k = 0;
for(int j=i+1;j<=n;j++)
if(mp[i][j]==0) a1[k++] = j;
tp.clear();
tp.push_back(i);
dfs(a1,k,1,tp);
num[i] = ans;
}
printf("%d\n",ans);
for(int i=0;i<ans;i++){
if(i) printf(" ");
printf("%d",vc[i]);
}
printf("\n");
}
int main(void){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
vis[i] = 0;
for(int j=1;j<=n;j++)
mp[i][j] = 0;
mp[i][i] = 1;
}
for(int i=1;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
mp[x][y] = mp[y][x] = 1;
}
fun();
}
return 0;
}