POJ【2989】All Friends(极大团的个数)

题目链接:http://poj.org/problem?id=2989
分析
这道题求的是极大团的个数,可以用Bron-Kerbosch算法。以下是我对该算法的个人理解,不对之处,欢迎指正。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define For(i,j,k) for(int i = j; i <= k; i++)
#define N 130
int a[N][N],all[N][N],some[N][N],none[N][N];
int ans;
void dfs(int n,int an,int sn,int nn)
{
	if(!sn && !nn) ans++;//所有点已选完,且没有不能选的点
	if(ans > 1000) return;
	int u = some[n][1];
	For(i,1,sn) {//枚举some中的每一个元素
		int v = some[n][i],tsn = 0,tnn = 0;
		if(a[u][v]) continue;//与v相关的点之前已经被搜索过
		For(j,1,an) all[n + 1][j] = all[n][j];//复制一份
		all[n + 1][an + 1] = v;//将v加入新的集合当中
		//some中只有与v有联系的点才能作为备选,none中也只有与v有联系的点才会对接下来造成影响
		For(j,1,sn) if(a[v][some[n][j]]) some[n + 1][++tsn] = some[n][j];
		For(j,1,nn) if(a[v][none[n][j]]) none[n + 1][++tnn] = none[n][j];
		dfs(n + 1,an + 1,tsn,tnn);//All ⋃ {v}, Some ⋂ N(v), None ⋂ N(v)
		//N(v):结点v的所有直接邻居(有边直接相连)结点的集合
		some[n][i] = 0,none[n][++nn] = v;//在some中删除v,none中加入v,关于这个点的所有极大团已经找到,之后与v相关的极大团就不会再次计入
	}
}
int main()
{
	int n,m;
	while(~scanf("%d%d",&n,&m)) {
		memset(a,0,sizeof(a));
		memset(all,0,sizeof(all));
		memset(some,0,sizeof(some));
		memset(none,0,sizeof(none));
		ans = 0;
		int u,v;
		For(i,1,m) {
			scanf("%d%d",&u,&v);
			a[u][v] = a[v][u] = 1;
		}
		For(i,1,n) some[1][i] = i;
		dfs(1,0,n,0);
		if(ans > 1000) printf("Too many maximal sets of friends.\n");
		else printf("%d\n",ans);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值