「题解」极大团 clique
Posted Lu_Anlai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「题解」极大团 clique相关的知识,希望对你有一定的参考价值。
本文将同步发布于:
题目
题目链接:POJ2989。
题意简述
给定一张 \\(n\\) 个点 \\(m\\) 条边的无向图,求极大团的个数。若极大团数超过 \\(10^3\\),输出 Too many maximal sets of friends.
。
\\(n\\leq 128\\)。
题解
极大团的数量是 Bron-Kerbosch 算法的典型应用,套用即可。
算法流程如下:
- 对于一个图 \\(G\\),我们将它分成四个部分:
- 在当前团中的点;
- 在当前团的邻域内的点(准备入团)
- 在当前邻域内的点(不准备入团,也就是之前统计过的点);
- 不在与当前团无边相连的点(不在邻域内的点);
- 我们每次从第二部分中选择一个点入团,并更新相应的集合;
- 当第二个集合为空时,我们不能扩大团,为极大团,准备回溯,若此时第三个集合为空,这个团之前并未搜索过,更新当前答案。
上面的方法可以每次找到一个团,但是时间复杂度仍然不够优秀,我们考虑去除重复状态,具体地,我们从第二个集合中选择一个代表点,如果当前点与代表点有边相连,则跳过当前点,因为我们一定会在加入代表点之后决定加入这个点,这样搜索没有改变状态,而减少了搜索的路径。
参考程序
#include<bits/stdc++.h>
using namespace std;
#define reg register
typedef long long ll;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
static char buf[1<<21],*p1=buf,*p2=buf;
inline int read(void){
reg char ch=getchar();
reg int res=0;
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) res=10*res+(ch^\'0\'),ch=getchar();
return res;
}
const int MAXN=128+5;
int n;
bool G[MAXN][MAXN];
unsigned int ans;
inline void dfs(vector<int> bas,vector<int> p,vector<int> n){
if(ans>1000u)
return;
if(!p.size()){
if(!n.size())
++ans;
return;
}
reg int pivot=p[0];
for(reg int i=0,siz=p.size();i<siz;++i){
int v=p[i];
if(G[pivot][v])
continue;
vector<int> np,nn;
for(reg int j=0;j<i;++j)
if(G[pivot][p[j]]&&G[v][p[j]])
np.push_back(p[j]);
for(reg int j=i+1;j<siz;++j)
if(G[v][p[j]])
np.push_back(p[j]);
for(int x:n)
if(G[v][x])
nn.push_back(x);
vector<int> nbas=bas;
nbas.push_back(v);
dfs(nbas,np,nn);
if(ans>1000u)
return;
n.push_back(v);
}
return;
}
int main(void){
reg int t=read();
while(t--){
reg int n=read();
for(reg int i=0;i<n;++i)
for(reg int j=0;j<n;++j)
G[i][j]=false;
reg int m=read();
for(reg int i=0;i<m;++i){
static int x,y;
x=read()-1,y=read()-1;
G[x][y]=G[y][x]=true;
}
vector<int> U;
U.resize(n);
for(reg int i=0;i<n;++i)
U[i]=i;
ans=0;
dfs(vector<int>{},U,vector<int>{});
if(ans>1000u)
puts("Too many maximal sets of friends.");
else
printf("%u\\n",ans);
}
return 0;
}
以上是关于「题解」极大团 clique的主要内容,如果未能解决你的问题,请参考以下文章
HDOJ5952Counting Cliques(团,dfs)