题目链接:hdu 5952 Counting Cliques
题目大意
n≤100 个点,m≤1000 条边的图,求大小恰好是 s≤10 的团的数量。
解题思路
因为题目中已经说了每个点的度不超过20,并且 s≤10 ,我们就可以按照每个节点为起点进行搜索,只要搜索到了就把答案+1,还有一个问题就是怎么保证搜索的时候不重复的问题,我们可以额外的申请一个数据结构,判断当前的节点是不是和已经在这个数据结构里面的点都有一条边,如果有就把这个点也加入这个数据结构,知道搜索到在这这个数据结构里面的点等于S就从下一个点继续搜索,直至所搜完毕!
AC代码
#include <cstdio>
#include <cstring>
const int MX = 1e3+5;
int m[MX][MX],head[MX],IN[MX],ans,e;
struct Edge{
int v,nxt;
}E[MX<<2];
void init()
{
ans = 0;
e=0;memset(IN,0,sizeof IN);
memset(head,-1,sizeof head);
memset(m,0,sizeof m);
}
void add(int u,int v)
{
E[e].v =v;
E[e].nxt = head[u];
head[u] = e++;
}
void DFS(int siz,int *A,int u,int s)
{
if(siz==s) {
ans++;
return ;
}
for(int i=head[u];~i;i=E[i].nxt) {
int v = E[i].v; bool flag = true;
for(int j=1;j<=siz;j++) {
if(!m[v][A[j]]) {
flag = false;
break;
}
}
if(flag) {
siz++;
A[siz] = v;
DFS(siz,A,v,s);
siz--;
}
}
}
void solve(int n,int s)
{
for(int i=1;i<=n;i++) {
int A[MX];memset(A,0,sizeof A);
A[1] = i;
DFS(1,A,i,s);
}
printf("%d\n",ans);
}
int main()
{
int T,N,M,S;freopen("in.txt","r",stdin);
scanf("%d",&T);
while(T--) {
init();
scanf("%d%d%d",&N,&M,&S);
while(M--) {
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
m[u][v] = m[v][u] = 1;
}
solve(N,S);
}
return 0;
}