HDU 5952 - Counting Cliques

来源:互联网 发布:转行it 知乎 编辑:程序博客网 时间:2024/05/29 21:29
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


题意:给出 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;}


0 0