http://poj.org/problem?id=2989
给n个点m条边,求极大团的数量。
极大团的定义就是:对于一个团里,所有人互为朋友,且团外的任何一个人,都不会和团里的所有人同时是朋友。
BK算法的伪代码
BronKerbosch(All, Some, None):
if Some and None are both empty:
report All as a maximal clique
for each vertex v in Some:
BronKerbosch1(All ⋃ {v}, Some ⋂ N(v), None ⋂ N(v))
Some := Some \ {v}
None := None ⋃ {v}
其实现:
void BronKerbosch(vector<int>all,vector<int>some,vector<int>none)
{
if (flag)return;
if (some.empty()&&none.empty())
{
ans++;
if (ans>1000)flag=1;
return;
}
for(int i=some.size()-1; i>=0; i--)
{
int v=some[i];
BronKerbosch(getUnion(all,v),getIntersection_v_neighbor(some,v),
getIntersection_v_neighbor(none,v));
if (flag)return;
none=getUnion(none,v);
some.erase(find(some.begin(),some.end(),v));
}
}
根据论文《A note on the problem of reporting maximal cliques》中提高的优化方法,选一个基准轴 pivot vertex u。
对于任意的最大团,其必须包括顶点u或者u的非邻接点.否则就可以添加顶点u来扩充极大团.