Counting Cliques
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 3700 Accepted Submission(s): 1322
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
34 3 21 22 33 45 9 31 31 41 52 32 42 53 43 54 56 15 41 21 31 41 51 62 32 42 52 63 43 53 64 54 65 6
Sample Output
3715
题意:给你n个点 m条边 计算有s个节点的完全子图的数目
思路:dfs;对每个点进行一次搜索,用一个temp数组保存已经加入团的点,每次加入一个新点的时候判断是否满足完全子图的条件;
ac代码:
#include<bits/stdc++.h>
using namespace std;
vector<int>G[105];
int ma[105][105];
int cnt,dis;
int n,m,s;
int temp[105];
void dfs(int x,int dis,int temp[105])
{
if(dis == s)
{
cnt ++;
return;
}
else
{
bool f;
for(int i = 0; i < G[x].size(); i++)
{
int v = G[x][i];
f = true;
for(int j = 1; j <= dis; j++)
{
if(!ma[v][temp[j]])
{
f = false;
break;
}
}
if(f)
{
dis++;
temp[dis] = v;
dfs(v,dis,temp);
temp[dis] = 0;
dis--;
}
}
}
return ;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(ma,0,sizeof(ma));
scanf("%d %d %d",&n,&m,&s);
for(int i = 1; i <= n; i++)
G[i].clear();
cnt = 0;
int x,y;
for(int i = 0; i < m; i++)
{
scanf("%d %d",&x,&y);
G[x].push_back(y);
ma[x][y] = ma[y][x] = 1;
}
for(int i = 1; i <= n; i++)
{
dis = 1;
temp[1] = i;
dfs(i,dis,temp);
}
printf("%d\n",cnt);
}
}