#include <bits/stdc++.h>
using namespace std;
const int SIZE = 55;
int Graph[SIZE][SIZE];
int inset[SIZE];//当前用到的的结点
int cn,n;//当前的节点数量,总点数
int bestn;//当前最大的节点数量
void DFS( int i ){
if ( i > n ) {
//此处可以记录最大团
bestn = cn;
return;
}
int flag = 1;
for (int j = 0 ;j < cn;++j )
if ( Graph[i][inset[j]] == 0){
flag = 0;
break;
}
if ( flag ) {
inset[cn++] = i;
DFS( i+1 );
cn--;
}
if ( cn + n - i > bestn )
DFS(i+1);
}
int main(){
cin>>n;
for (int i = 1;i <= n;++i )
for (int j = 1;j <= n;++j )
scanf("%d",&Graph[i][j]);
DFS(1);
int ans = bestn;
printf("%d\n",ans);
return 0;
}
最大团&最大独立集
经典的NP完全问题,只有暴力解,时间复杂度O(n2^n)
对于无向图来说
所谓最大团, 其实就是找一个最大完全子图,最大就是包含的点最多.
而最大独立集 == 补图的最大团
这里使用深度优先搜索实现,对于每一个结点,考虑要与不要两种状态,则问题构成一个子集树,本质上与01背包一样,只不过多了联通性的判断
模板样例
In
3
0 1 1……结点1到2有边,结点2到3有边
1 0 0……结点2到1有边
0 0 0
Out
2……最大团是1-2