Counting Cliques(HDU-5952)【DFS】

题目链接:https://vjudge.net/problem/HDU-5952

题意:有一张无向图,求结点数量为S的团的数量。

思路:如果不加一点处理直接用DFS必然会超时,因为在搜索过程中会出现遍历多次重复团的情况。

   tips:我们重复遍历团,更直接地过程其实是将”5 4 3 2 1“与”5 4 2 3 1“没有区分开,所以,我们建图时将无向边改为小号结点指向大号结点的有向边,并用邻接矩阵来记录两点是否存在边,然后就可以进行DFS啦!!

代码如下:

#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
vector<int> ha[110];
int t, n, m, s;
int g[110][110];
int a[110];
int ans;
void dfs(int x)
{
    if (a[0] == s)
    {
        ans++;
        return;
    }
    for (int ii = 0; ii < ha[x].size(); ii++)
    {
        int i = ha[x][ii];
        int flag = 0;
        for (int j = 1; j <= a[0]; j++)
        {
            if (!g[i][a[j]])
            {
                flag = 1;
                break;
            }
        }
        if (!flag)
        {
            a[++a[0]] = i;
            dfs(i);
            a[0]--;
        }
    }
}
int main()
{
    scanf("%d", &t);
    while (t--)
    {
        ans = 0;
        a[0] = 0;
        memset(g, 0, sizeof(g));
        scanf("%d%d%d", &n, &m, &s);
        for(int i=1;i<=n;i++)
            ha[i].clear();
        int u, v;
        while (m--)
        {
            scanf("%d%d", &u, &v);
            if (u < v)
                ha[u].push_back(v);
            else
                ha[v].push_back(u);
            g[u][v] = 1;
            g[v][u] = 1;
        }
        for (int i = 1; i <= n; i++)
        {
            a[++a[0]] = i;
            dfs(i);
            a[0]--;
        }
        printf("%d\n", ans);
    }
    return 0;
}

 

posted @ 2019-11-14 21:55  xxmlala  阅读(42)  评论(0编辑  收藏