首先介绍一些基本概念:
1、什么是团?如果一个子图是一个无向图的完全子图,那么可以称为一个团。
2、什么是极大团?如果一个团不是任何一个团的子集,那么可以称做一个极大团。
3、如果一个极大团的大小是最大的,那么可以被称为一个最大团。
最大团有以下常见性质,这里不加证明的直接给出结论。
最大团点的数量等于其补图中最大独立集的数量(最大团与最大独立集的关系)。特别的,在二分图中,最大独立集=顶点数-最大匹配数。(这个很好理解,因为找到补图中的最大团,在图中这些边都是不存在的,并且是点个数最多的。)
下面给出模板:(HDU 1530)
#include<bits/stdc++.h>
using namespace std;
const int N = 105;
int n, G[N][N];
int cntClique, pts[N], res[N], cnt[N];
bool dfs(int pos, int num){
for(int i=pos+1;i<=n;++i){
if(cnt[i]+num<=cntClique)return false;//这里是一处剪枝
if(G[pos][i]){//考虑与当前团节点的关系
int ok=1;
for(int id=1;id<=num;++id){
if(!G[i][pts[id]]){
ok=0;break;
}
}
if(ok){
pts[num+1]=i;
if(dfs(i,num+1))return true;
}
}
}
if(num>cntClique){ //多枚举一个,最多只扩充一个点
for(int i=1;i<=num;++i){
res[i]=pts[i];
}
cntClique=num;
return true;
}
return false;
}
void maxClique(){
cntClique=-1;
for(int i=n;i>0;--i){
pts[1]=i;
dfs(i,1);
cnt[i]=cntClique;
}
}
int main(){
while(scanf("%d",&n)&&n){
memset(G,0,sizeof G);
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
scanf("%d",&G[i][j]);
}
}
maxClique();
printf("%d
",cntClique);
}
return 0;
}
POJ(1419)
#include<cstdio>
#include<cstring>
//#include<bits/stdc++.h>
using namespace std;
const int N = 105;
int n, m, G[N][N];
int cntClique, pts[N], res[N], cnt[N];
bool dfs(int pos, int num){
for(int i=pos+1;i<=n;++i){
if(cnt[i]+num<=cntClique)return false;//这里是一处剪枝
if(G[pos][i]){//考虑与当前团节点的关系
int ok=1;
for(int id=1;id<=num;++id){
if(!G[i][pts[id]]){
ok=0;break;
}
}
if(ok){
pts[num+1]=i;
if(dfs(i,num+1))return true;
}
}
}
if(num>cntClique){ //多枚举一个,最多只扩充一个点
for(int i=1;i<=num;++i){
res[i]=pts[i];
}
cntClique=num;
return true;
}
return false;
}
void maxClique(){
cntClique=-1;
for(int i=n;i>0;--i){
pts[1]=i;
dfs(i,1);
cnt[i]=cntClique;
}
}
int main(){
int T;scanf("%d",&T);
while(T--){
memset(G,0,sizeof G);
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i){
int u,v;scanf("%d%d",&u,&v);
G[u][v]=1;G[v][u]=1;
}
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if(i==j)G[i][j]=0;
else{
G[i][j]^=1;
}
}
}
maxClique();
printf("%d
",cntClique);
for(int i=1;i<=cntClique;++i){
printf("%d ",res[i]);
}
}
return 0;
}