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 }