Counting Cliques
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 4101 Accepted Submission(s): 1448
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
题意:
给定一个图,找出该图中节点数为S的完全图。
分析:
直接暴力,但是在暴力的过程中会出现情况相同的情况,比如第一个样例中的1-2和2-1是一个完全图。因此在建边的时候默认是从小的标号连接大的标号,并且是有向边,这样就可以避免一个完全图被重复计算的问题了。
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn=105;
typedef long long ll;
struct node
{
int to;
int next;
}edge[10000*4];
bool mp[maxn][maxn];
bool vis[maxn];
int n,m,s;
int ans[maxn];
int idex=0;
ll sum=0;
int cnt=0;
int head[10000*4];
void add(int a,int b)
{
edge[++cnt].to=b;
edge[cnt].next=head[a];
head[a]=cnt;
}
void dfs(int x)
{
if(idex==s)
{
sum++;
return ;
}
for(int i=head[x];i!=-1;i=edge[i].next)
{
if(mp[x][edge[i].to])
{
if(vis[edge[i].to]) continue;
int flog=0;
for(int j=1;j<=idex;j++)
{
if(!mp[ans[j]][edge[i].to])
{
flog=1;
break;
}
}
if(flog)
continue;
vis[edge[i].to]=true;
ans[++idex]=edge[i].to;
dfs(edge[i].to);
idex--;
vis[edge[i].to]=false;
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
cnt=0;
sum=0;
memset(head,-1,sizeof(head));
memset(vis,false,sizeof(vis));
memset(mp,false,sizeof(mp));
scanf("%d%d%d",&n,&m,&s);
for(int i=1;i<=m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
if(a>b)
swap(a,b);
add(a,b);
// add(b,a);
mp[a][b]=true;
mp[b][a]=true;
}
for(int i=1;i<=n;i++)
{
idex=0;
vis[i]=true;
ans[++idex]=i;
dfs(i);
vis[i]=false;
}
printf("%lld\n",sum);
}
return 0;
}
/*
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
*/