( 图论专题 )【最大团 】

( 图论专题 )【最大团 】

最大团是什么:通俗点讲就是在一个无向图中找出一个点数最多的完全图

当 G′ 是图 G 的子图,且 G′ 是关于 V′ 的完全图时,子图 G' 为图 G 的团;当 G' 是团,且不是其他团的子集时,G' 为图 G 的极大团;当 G' 是极大团时,且点数最多,G' 为图 G 最大团

当 G′ 中所有点不相邻,最大点集最大的图 G′ 为图 G 的最大独立集,且最大独立集数=补图的最大团

 

当用个数最少的团覆盖图 G 所有的点时,称为最小团覆盖,由于每个团中最多取一个点,因此有最大独立集<=最小团覆盖

简单来说,极大团是增加任一顶点都不再符合定义的团,最大团是图中含顶点数最多的极大团,最大独立集是除去图中的团后的点集,而最大团问题就是在一个无向图中找出一个点数最多的完全图。

对于弦图来说,求最大团一般使用 MCS 算法,而对于一般图来说,常使用 Bron-Kerbosch 算法

关于弦图的最大团:点击这里

Bron-Kerbosch 算法

Bron-Kerbosch 算法用于计算图中的最大的全连通分量,即计算图的最大团。

#include <bits/stdc++.h>

using namespace std;

int mp[105][105];
int len[1005],mc[1005],res,lis[105][105];
bool found;
int n;

void dfs(int sz){
    int i, j, k;
    if(len[sz] == 0){
        if(sz > res){
            res = sz;
            found = true;
        }
        return;
    }
    for(k = 0; k < len[sz] && !found; ++k){
        if(sz + len[sz] - k <= res){
            break;
        }
        i = lis[sz][k];
        if(sz + mc[i] <= res)break;
        for(j = k + 1,len[sz+1]=0; j < len[sz]; ++j){
            if(mp[i][lis[sz][j]]){
                lis[sz+1][len[sz+1]++] = lis[sz][j];
            }
        }
        dfs(sz+1);
    }
}
void max_tuan(){
    int i, j;
    mc[n] = res = 1;
    for(i = n-1;i;--i){
        found=false;
        len[1] = 0;
        for(j = i+1; j <= n; j++){
            if(mp[i][j]){
                lis[1][len[1]++] = j;
            }
        }
        dfs(1);
        mc[i] = res;
    }
}
int main()
{
    cin>>n>>m;
    for ( int i=0; i<m; i++ ) {
        int u,v;cin>>u>>v;
        mp[u][v] = mp[v][u] = 1;
    }
    max_tuan();
    cout << res << endl;

    return 0;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值