初始化集合 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 中任意顶点间都两两相邻
伪代码过程
1 2 3 4 5 6 7
BronKerbosch1(R,P,X): if P and X are both empty: report R as a maximal clique for each vertex v in P: BronKerbosch1(R ⋃ {v}, P ⋂ N(v), X ⋂ N(v)) P := P \ {v} X := X ⋃ {v}
BronKerbosch2(R,P,X): if P and X are both empty: report R as a maximal clique choose a pivot vertex u in P ⋃ X for each vertex v in P \ N(u): BronKerbosch2(R ⋃ {v}, P ⋂ N(v), X ⋂ N(v)) P := P \ {v} X := X ⋃ {v}
BronKerbosch3(G): P = V(G) R = X = empty for each vertex v in a degeneracy ordering of G: BronKerbosch2(R ⋃ {v}, P ⋂ N(v), X ⋂ N(v)) P := P \ {v} X := X ⋃ {v}
int n,m; bool G[N][N]; int cnt[N];//cnt[i]为>=i的最大团点数 int group[N];//最大团的点 int vis[N];//记录点的位置 int res;//最大团的数目 booldfs(int pos,int num){//num为当前独立集中的点数 for(int i=pos+1;i<=n;i++){ if(cnt[i]+num<=res)//剪枝,若取i但cnt[i]+已经取了的点数仍<ans returnfalse;