最大团学习地址:http://www.cnblogs.com/pushing-my-way/archive/2012/08/08/2627993.html
最大团=补图的最大独立集。
也就是所有互相不相连的点。
- #include <cstdio>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- const int MAXN = 105;
- struct MaxClique {
- bool g[MAXN][MAXN];
- int n, dp[MAXN], st[MAXN][MAXN], ans;
- // dp[i]表示第i个点之后能组成的最大团的大小,
- // st[i][j]表示算法中第i层dfs所需要的点的集合,保存有可能是最大团其中之一的点
- void init(int n) {
- this->n = n;
- memset(g, false, sizeof(g));
- }
- void addedge(int u, int v, int w) {
- g[u][v] = w;
- }
- bool dfs(int sz, int num) {
- if (sz == 0) {
- if (num > ans) {
- ans = num;
- return true;
- }
- return false;
- }
- for (int i = 0; i < sz; i++) { // 在第num层的集合中枚举一个点i
- if (sz - i + num <= ans) return false; // 剪枝1
- int u = st[num][i];
- if (dp[u] + num <= ans) return false; // 剪枝2
- int cnt = 0;
- for (int j = i + 1; j < sz; j++) { // 在第num层遍历在i之后的且与i所相连的点,并且加入第num+1层集合
- if (g[u][st[num][j]])
- st[num + 1][cnt++] = st[num][j];
- }
- if (dfs(cnt, num + 1)) return true;
- }
- return false;
- }
- int solver() {
- ans = 0;
- memset(dp, 0, sizeof(dp));
- for (int i = n; i >= 1; i--) {
- int cnt = 0;
- for (int j = i + 1; j <= n; j++) { // 初始化第1层集合
- if (g[i][j]) st[1][cnt++] = j;
- }
- dfs(cnt, 1);
- dp[i] = ans;
- }
- return ans;
- }
- }maxclique;
- int main() {
- int n;
- while (scanf("%d", &n), n) {
- maxclique.init(n);
- for (int i = 1; i <= n; i++) {
- for (int j = 1; j <= n; j++) {
- int x;
- scanf("%d", &x);
- maxclique.addedge(i, j, x);
- }
- }
- printf("%d\n", maxclique.solver());
- }
- return 0;
- }
#include <iostream>
#include <memory.h>
#include <stdio.h>
using namespace std;
const int maxnum=101;
bool array[maxnum][maxnum];
bool use[maxnum]; //进入团的标号
int cn,bestn,p,e;
void dfs(int i)
{
int j;
bool flag;
if(i>p)
{
bestn=cn;
printf("%d\n",bestn);
for(j=1;j<=p;j++)
if(use[j])
printf("%d ",j);
printf("\n");
return ;
}
flag=true;
for(j=1;j<i;j++)
if(use[j]&&!array[j][i])
{
flag=false;
break;
}
if(flag)
{
cn++;
use[i]=true;
dfs(i+1);
cn--;
}
if(cn+p-i>bestn) //剪枝
{
use[i]=false;
dfs(i+1);
}
}
int main()
{
int num,i,u,v;
scanf("%d",&num);
while(num--)
{
memset(array,false,sizeof(array));
memset(use,false,sizeof(use));
scanf("%d%d",&p,&e);
for(i=0;i<e;i++)
{
scanf("%d%d",&u,&v);
array[u][v]=true;
array[v][u]=true;
}
cn=bestn=0;
dfs(1);
//printf("%d\n",bestn);
}
return 0;
}
/*
1
5 7
1 2
1 4
1 5
2 3
2 5
3 5
4 5
*/