最大团问题

来源:互联网 发布:小米3怎么用4g网络 编辑:程序博客网 时间:2024/06/05 08:53

最大团学习地址:http://www.cnblogs.com/pushing-my-way/archive/2012/08/08/2627993.html

最大团=补图的最大独立集。

也就是所有互相不相连的点。

  1. #include <cstdio>  
  2. #include <cstring>  
  3. #include <iostream>  
  4. #include <algorithm>  
  5. using namespace std;  
  6. const int MAXN = 105;  
  7.   
  8. struct MaxClique {  
  9.     bool g[MAXN][MAXN];  
  10.     int n, dp[MAXN], st[MAXN][MAXN], ans;  
  11.     //  dp[i]表示第i个点之后能组成的最大团的大小,  
  12.     //  st[i][j]表示算法中第i层dfs所需要的点的集合,保存有可能是最大团其中之一的点   
  13.   
  14.     void init(int n) {  
  15.         this->n = n;  
  16.         memset(g, falsesizeof(g));  
  17.     }  
  18.   
  19.     void addedge(int u, int v, int w) {  
  20.         g[u][v] = w;  
  21.     }  
  22.   
  23.     bool dfs(int sz, int num) {  
  24.         if (sz == 0) {  
  25.             if (num > ans) {  
  26.                 ans = num;  
  27.                 return true;  
  28.             }  
  29.             return false;  
  30.         }  
  31.         for (int i = 0; i < sz; i++) {       // 在第num层的集合中枚举一个点i  
  32.             if (sz - i + num <= ans) return false;   // 剪枝1  
  33.             int u = st[num][i];  
  34.             if (dp[u] + num <= ans) return false;    // 剪枝2  
  35.             int cnt = 0;  
  36.             for (int j = i + 1; j < sz; j++) {   // 在第num层遍历在i之后的且与i所相连的点,并且加入第num+1层集合  
  37.                 if (g[u][st[num][j]])   
  38.                     st[num + 1][cnt++] = st[num][j];  
  39.             }  
  40.             if (dfs(cnt, num + 1)) return true;  
  41.         }  
  42.         return false;  
  43.     }  
  44.   
  45.     int solver() {  
  46.         ans = 0;  
  47.         memset(dp, 0, sizeof(dp));  
  48.         for (int i = n; i >= 1; i--) {  
  49.             int cnt = 0;  
  50.             for (int j = i + 1; j <= n; j++) {   // 初始化第1层集合  
  51.                 if (g[i][j]) st[1][cnt++] = j;  
  52.             }  
  53.             dfs(cnt, 1);  
  54.             dp[i] = ans;  
  55.         }  
  56.         return ans;  
  57.     }  
  58.   
  59. }maxclique;   
  60.   
  61. int main() {  
  62.     int n;  
  63.     while (scanf("%d", &n), n) {  
  64.         maxclique.init(n);  
  65.         for (int i = 1; i <= n; i++) {  
  66.             for (int j = 1; j <= n; j++) {  
  67.                 int x;  
  68.                 scanf("%d", &x);  
  69.                 maxclique.addedge(i, j, x);  
  70.             }  
  71.         }  
  72.         printf("%d\n", maxclique.solver());  
  73.     }  
  74.     return 0;  
  75. }  



#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
*/

原创粉丝点击