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
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
题意:给出 n 个点,m 条边,一个数量 s,将这个图分为几个完全子图,每个完全子图的点的数量是数量 s,问一共能分为多少个完全子图。
总之大体思路就是遍历每一个点,将与它相连的都遍历一遍,并且遍历每个点之后就将这个点从图上删去。
PS 一开始想用组合数直接算出来,但是这样可能重复\漏掉情况,看来我还是拿衣服。。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
bool vis[105][105];
int degree[105], order[105];
int head, s, ans;
vector<int> vec[105];
void DFS(int u, int n)
{
if (head == s)
{
ans++;
return;
}
if (vec[u].size() - n < s - head || n >= vec[u].size())
return;
int cnt = 0;
for (int i = 0; i < head; ++i)
{
if (!vis[vec[u][n]][order[i]])
{
cnt = 1;
break;
}
}
if (cnt == 0)
{
order[head++] = vec[u][n];
DFS(u, n+1);
head--;
}
DFS(u, n+1);
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
int n, m;
scanf("%d%d%d", &n, &m, &s);
memset(vis, false, sizeof(vis));
memset(degree, 0, sizeof(degree));
memset(order, 0, sizeof(order));
for (int i = 0; i < 105; ++i)
vec[i].clear();
for (int i = 0; i < m; ++i)
{
int u, v;
scanf("%d%d", &u, &v);
degree[u]++;
degree[v]++;
vis[u][v] = vis[v][u] = 1;
vec[u].push_back(v);
vec[v].push_back(u);
}
ans = 0;
for (int i = 1; i <= n; ++i)
{
if (degree[i] < s-1)
continue;
head = 0;
order[head++] = i;
DFS(i, 0);
for (int j = 1; j <= n; ++j)
{
if (vis[i][j])
{
degree[j]--;
vis[i][j] = vis[j][i] = false;
}
}
}
printf("%d\n", ans);
}
return 0;
}