最大团: V中取K个顶点,两点间相互连接
最大独立集: V中取K个顶点,两点间不连接
最大团数量 = 补图中最大独立集数
基础形式是一个递归回溯的搜索算法.通过给定三个集合 (R,P,X).
初始化集合R,X分别为空,而集合P为所有顶点的集合.
而每次从集合P中取顶点{v}, 当集合中没有顶点时,两种情况.
1. 集合 R 是最大团, 此时集合X为空.
2. 无最大团,此时回溯.
对于每一个从集合P中取得得顶点{v},有如下处理:
1. 将顶点{v}加到集合R中, 集合P,X 与 顶点{v}得邻接顶点集合 N{v}相交, 之后递归集合 R,P,X
2. 从集合P中删除顶点{v},并将顶点{v}添加到集合X中.
若 集合 P,X都为空, 则集合R即为最大团.
总的来看就是每次从 集合P中取v后,再在 P∩N{v} 集合中取,一直取相邻,保证集合R中任意顶点间都两两相邻…
#include<cstdio>
#include<cstring>
#define N 1010
bool flag[N], a[N][N];
int ans, cnt[N], group[N], n, vis[N];
bool dfs( int u, int pos ){
int i, j;
for( i = u+1; i <= n; i++){
if( cnt[i]+pos <= ans ) return 0;
if( a[u][i] ){
// 与目前团中元素比较,取 Non-N(i)
for( j = 0; j < pos; j++ ) if( !a[i][ vis[j] ] ) break;
if( j == pos ){ // 若为空,则皆与 i 相邻,则此时将i加入到 最大团中
vis[pos] = i;
if( dfs( i, pos+1 ) ) return 1;
}
}
}
if( pos > ans ){
for( i = 0; i < pos; i++ )
group[i] = vis[i]; // 最大团 元素
ans = pos;
return 1;
}
return 0;
}
void maxclique()
{
ans=-1;
for(int i=n;i>0;i--)
{
vis[0]=i;
dfs(i,1);
cnt[i]=ans;
}
}