Counting Cliques
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 3843 Accepted Submission(s): 1380
Problem Description
A clique is a complete graph, in which there is an edge between every pair of the vertices. Given a graph with N vertices and M edges, your task is to count the number of cliques with a specific size S in the graph.
Input
The first line is the number of test cases. For each test case, the first line contains 3 integers N,M and S (N ≤ 100,M ≤ 1000,2 ≤ S ≤ 10), each of the following M lines contains 2 integers u and v (1 ≤ u < v ≤ N), which means there is an edge between vertices u and v. It is guaranteed that the maximum degree of the vertices is no larger than 20.
Output
For each test case, output the number of cliques with size S in the graph.
Sample Input
3
4 3 2
1 2
2 3
3 4
5 9 3
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
6 15 4
1 2
1 3
1 4
1 5
1 6
2 3
2 4
2 5
2 6
3 4
3 5
3 6
4 5
4 6
5 6
Sample Output
3
7
15
Source
2016ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)
Recommend
jiangzijing2015 | We have carefully selected several similar problems for you: 6408 6407 6406 6405 6404
[题目来源]http://acm.hdu.edu.cn/showproblem.php?pid=5952
题意:有n个人,有m种相互认识的关系,求共有多少种不同的方案,使得这s个人相互都认识;
题解:最早想到组合数,最多只有C【n】【s】种情况,再减去所有多算的部分,小数据貌似可行,但n的范围100,组合数一定炸,又因为保证每个人最多认识20人,而C【20】【9】刚好不炸,但不能直接暴搜,需要少些保存的状态,于是利用单调性,只用vector保存比当前大的人的边,优化后能过。用now数组来保存当前总数为size的人都相互认识,即深搜时维护起点,已经那些人入了圈(圈内人互相认识),圈的大小。
附AC代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stdio.h>
#include<vector>
using namespace std;
const int maxn=110;
int n,m,s,u,v,size,mp[maxn][maxn],ans,t;
vector<int> g[maxn];
void dfs(int u,int now[],int size)
{
if(size==s)
{
ans++;
return;
}
bool ok=1;
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
ok=1;
for(int j=1;j<=size;j++)
if(!mp[v][now[j]])
{
ok=0;
break;
}
if(ok)
{
now[++size]=v;
dfs(v,now,size);
now[size--]=0;
}
}
}
int main()
{
scanf("%d",&t);
while(t--)
{
cin>>n>>m>>s;
for(int i=1; i<=n; i++) g[i].clear();
memset(mp,0,sizeof(mp));
ans=0;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
if(u>v) swap(u,v);
g[u].push_back(v);
mp[u][v]=mp[v][u]=1;
}
for(int i=1;i<=n;i++)
{
size=1;
int now[maxn];
now[1]=i;
dfs(i,now,size);
}
printf("%d\n",ans);
}
}