HDU 5952 Counting Cliques 爆搜

题目

      HDU 5952

分析

      题目数据很小,可以考虑暴力搜索。为了防止重复,建立一个小编号点指向大编号点的图,这样就不会重复了,因为搜索出来的序列一定是递增的。
      这道题目让我懂得了,有时候TLE,不要总想着改进算法,要先确定自己的代码没有任何问题才行。这道题目就是因为一个手误,TLE了,然后就在那里一直想着怎么剪枝。

代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <set>

using namespace std;
const int maxn = 105;
int N, M, S;
int G1[maxn][maxn];
vector<int> G2[maxn];
int pre[maxn], cnt;
int ans;

void dfs(int u)
{
    for (int i = 0; i < cnt; i++) {
        if (!G1[u][pre[i]]) {
            return;
        }
    }
    pre[cnt++] = u;
    if (cnt == S) {
        ans++;
        cnt--;
        return;
    }
    for (unsigned i = 0; i < G2[u].size(); i++) {
        dfs(G2[u][i]);
    }
    cnt--;
}

int main()
{
    //freopen("test.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    int T;
    scanf("%d", &T);
    while (T--) {
        memset(G1, 0, sizeof(G1));
        for (int i = 0; i < maxn; i++) {
            G2[i].clear();
        }
        scanf("%d%d%d", &N, &M, &S);
        for (int i = 0; i < M; i++) {
            int u, v;
            scanf("%d%d", &u, &v);
            G1[u][v] = G1[v][u] = 1;
            if (u > v) swap(u, v);
            G2[u].push_back(v);
        }
        ans = 0;
        for (int i = 1; i <= N; i++) {
            cnt = 0;
            dfs(i);
        }
        printf("%d\n", ans);
    }
    return 0;
}
点赞