最大团 hdu1530

最大团也就是最大完全图

给定一个无向图 G=(V,E),若对任意两个顶点 u、v ∈U,有 (u,v)∈E,则称 U 是 G 的完全子图,G 的完全子图 U 称为图 G 的团。

    极大团:一个团不被其他任一团所包含,即其不是任一团的真子集
    最大团:在 V 中取最多的点,满足任意两点间相互连接
    最大独立集:在 V 中取最多的点,满足任意两点间不连接(最大独立集数=补图的最大团)

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

Bron-Kerbosch 算法】

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

Bron-Kerbosch 算法的基础形式是一个递归回溯的搜索算法,其通过给定三个集合:R、P、X 来递归的进行搜索

    初始化集合 R、X 分别为空,集合 P 为所有顶点的集合
    每次从集合 P 中取顶点 {vi},当集合中没有顶点时,有两种情况:
    1)集合 R 是最大团,此时集合 X 为空
    2)无最大团,此时回溯
    对于每一个从集合 P 中取得的顶点 {vi},有如下处理:
    1)将顶点 {vi} 加到集合 R 中,集合 P、X 与顶点 {vi} 得邻接顶点集合 N{vi} 相交,之后递归集合 R、P、X
    2)从集合 P 中删除顶点 {vi},并将顶点 {vi} 添加到集合 X 中
    3)若集合 P、X 都为空,则集合 R 即为最大团

总的来看,就是每次从集合 P 中取 vi 后,再从 P∩N{vi} 集合中取相邻结点,保证集合 R 中任意顶点间都两两相邻
以上来自:https://blog.csdn.net/u011815404/article/details/86609798


传送门

Given a graph G(V, E), a clique is a sub-graph g(v, e), so that for all vertex pairs v1, v2 in v, there exists an edge (v1, v2) in e. Maximum clique is the clique that has maximum number of vertex.

Input

Input contains multiple tests. For each test:

The first line has one integer n, the number of vertex. (1 < n <= 50)

The following n lines has n 0 or 1 each, indicating whether an edge exists between i (line number) and j (column number).

A test with n = 0 signals the end of input. This test should not be processed.

Output

One number for each test, the number of vertex in maximum clique.

输入

5

0 1 1 0 1
1 0 1 1 1
1 1 0 1 1
0 1 1 0 1
1 1 1 1 0
0

Sample Output

4

///求最大团


#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn = 60;
int cnt[maxn],mp[maxn][maxn],vis[maxn],group[maxn];
int n,m,res;
void read(){
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
		scanf("%d",&mp[i][j]);
}
bool dfs(int pos,int num){
	for(int i=pos+1;i<=n;i++){
		if(cnt[i]+num<=res) return false;
		if(mp[pos][i]){
			int j;
			for(j=0;j<num;j++)
				if(mp[i][vis[j]]==0) break;
			if(j==num){ //j和团里所有点有边
				vis[num]=i;
				if( dfs(i,num+1) ) return true;
			}
		}
	}
	if(num>res){  //每次dfs只能加一个点,加到就结束此次
		res = num;
	/*	for(int i=0;i<num;i++)
		group[i]=vis[i];*/ 
		return true;
	}
	return false;
}
void maxcilque(){
	res=-1;
	for(int i=n;i>0;i--){
		vis[0]=i;
		dfs(i,1);
		cnt[i]=res;
	} 
}
int main(){
	while(scanf("%d",&n) && n){
		memset(mp,0,sizeof mp);
		memset(vis,0,sizeof vis);
		memset(cnt,0,sizeof cnt);
		read();
		maxcilque();
		printf("%d\n",res);
		/*for(int i=0;i<res;i++)
		cout<<group[i]<<" ";*/		
	}
	return 0;
} 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值