Counting Cliques HDU

题目:题目链接

思路:这道题vj上Time limit:4000 ms,HDU上Time Limit: 8000/4000 MS (Java/Others),且不考虑oj测评机比现场赛慢很多,但10月5号的计蒜客重现赛只给了1000ms确实有点过分吧,好久没有做这种简单dfs做到自闭了,,,题目并不难,注意剪枝就好了,建图时建标号小的点指向标号大的点的单向边,这样按标号从小到大搜一遍就好了,完全图的任意两个点都要有边,按点的标号搜到第n-s+1个点,因为后面所有的点加起来都组不成点数为s的完全子图。

AC代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <vector>
 6 
 7 using namespace std;
 8 
 9 const int maxn = 105;
10 
11 vector<int> G[maxn];
12 int num[maxn];
13 int g[maxn][maxn];
14 
15 int n, m, s, ans;
16 
17 void init();
18 void dfs(int, int);
19 bool judge(int, int);
20 
21 int main()
22 {
23     freopen("in.txt", "r", stdin);
24     int T, u, v;
25     scanf("%d", &T);
26     while(T--) {
27         scanf("%d %d %d", &n, &m, &s);
28         init();
29         for(int i = 0; i < m; ++i) {
30             scanf("%d %d", &u, &v);
31             if(u > v) {
32                 G[v].push_back(u);
33                 g[v][u] = 1;
34             }
35             else {
36                 G[u].push_back(v);
37                 g[u][v] = 1;
38             }
39         }
40 
41         ans = 0;
42         int t = n - s + 1;
43         for(int i = 1; i <= t; ++i) {
44             num[0] = i;
45             dfs(i, 1);
46         }
47 
48         printf("%d
", ans);
49     }
50     return 0;
51 }
52 
53 void init() {
54     for(int i = 1; i <= n; ++i)
55         G[i].clear();
56     memset(g, 0, sizeof(g));
57 }
58 
59 bool judge(int id, int dep) {
60     for(int i = 0; i < dep; ++i) {
61         if(!g[num[i]][id])
62             return false;
63     }
64     return true;
65 }
66 
67 void dfs(int id, int dep) {
68     if(dep == s) {
69         ++ans;
70         return ;
71     }
72     for(int i = 0; i < G[id].size(); ++i) {
73         if(G[id][i] > id && judge(G[id][i], dep)) {
74             num[dep] = G[id][i];
75             dfs(G[id][i], dep + 1);
76         }
77     }
78 }