E - Counting Cliques 暴力剪枝

题意:给出n个点,m条无向边,一个数字S

          求:完全图(团)大小为S的个数

思路:直接暴力即可,然后在边缘条件剪纸

   为了避免重复情况,我们对于每条边的建边方式为:小往大建边

   然后分别从1~n开始枚举

   这样子的操作,就能让有1顶点的枚举1~n

             有2顶点的枚举2~n

             有3顶点的枚举3~n

   

 1 //#pragma comment(linker,"/STACK:1024000000,1024000000")
 2 #include<bits/stdc++.h>
 3 #include<cstring>
 4 #define ll long long
 5 #define INF 1000000007
 6 using namespace std;
 7 int n,m,s,ans;
 8 vector<int> e[200];
 9 vector<int> sol;
10 bool b[200][200];
11 bool check(int x)
12 {
13     int len=sol.size();
14     for(int i=0;i<len;++i)
15         if(b[sol[i]][x]==0) return 0;
16     return 1;
17 }
18 void dfs(int tmp)
19 {
20     int len=e[tmp].size();
21     if(sol.size()==s)
22     {
23         ++ans;
24         return;
25     }
26     for(int i=0;i<len;++i){
27         if(check(e[tmp][i]))
28         {
29             sol.push_back(e[tmp][i]);
30             dfs(e[tmp][i]);
31             sol.pop_back();
32         }
33     }
34 }
35 int main()
36 {
37     int T,x,y;
38     scanf("%d",&T);
39     while(T--){
40         scanf("%d%d%d",&n,&m,&s);
41         ans=0;
42         memset(b,0,sizeof(b));
43         for(int i=0;i<=n+10;++i)
44             e[i].clear();
45         for(int i=1;i<=m;++i){
46             scanf("%d%d",&x,&y);
47             if(x>y)swap(x,y);
48             e[x].push_back(y);
49             b[x][y]=b[y][x]=1;
50         }
51         for(int i=1;i<=n;++i){
52             sol.clear();
53             sol.push_back(i);
54             dfs(i);
55         }
56         printf("%d\n",ans);
57     }
58     return 0;
59 }
View Code

 

posted @ 2021-01-21 20:22  古比  阅读(134)  评论(0编辑  收藏  举报