[HDOJ5952]Counting Cliques(DFS,剪枝)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5952
题意:求图中规模为s的团的个数。
DFS+剪枝,姿势不好很容易TLE啊。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 110; 5 int n, m, s, ret; 6 int dig[maxn]; 7 int G[maxn][maxn]; 8 int tmp[maxn], t; 9 int edge[maxn][maxn]; 10 int id[maxn]; 11 12 void dfs(int u) { 13 if(u > s) { 14 ret++; 15 return; 16 } 17 for(int i = 0; i < id[tmp[u-1]]; i++) { 18 int v = edge[tmp[u-1]][i]; 19 if(id[v] < s - u) continue; 20 if(n - v + 1 + u < s) return; 21 bool flag = 0; 22 for(int j = 1; j < u; j++) { 23 if(!G[v][tmp[j]]) { 24 flag = 1; 25 break; 26 } 27 } 28 if(!flag) { 29 tmp[u] = v; 30 dfs(u+1); 31 tmp[u] = 0; 32 } 33 } 34 } 35 36 inline bool scan_d(int &num) { 37 char in;bool IsN=false; 38 in=getchar(); 39 if(in==EOF) return false; 40 while(in!='-'&&(in<'0'||in>'9')) in=getchar(); 41 if(in=='-'){ IsN=true;num=0;} 42 else num=in-'0'; 43 while(in=getchar(),in>='0'&&in<='9'){ 44 num*=10,num+=in-'0'; 45 } 46 if(IsN) num=-num; 47 return true; 48 } 49 50 int main() { 51 // freopen("in", "r", stdin); 52 int T, u, v; 53 scan_d(T); 54 while(T--) { 55 scan_d(n);scan_d(m);scan_d(s); 56 ret = 0; 57 memset(edge, 0, sizeof(edge)); 58 memset(id, 0, sizeof(id)); 59 memset(G, 0, sizeof(G)); 60 memset(dig, 0, sizeof(dig)); 61 memset(tmp, 0, sizeof(tmp)); 62 for(int i = 0; i < m; i++) { 63 scan_d(u);scan_d(v); 64 G[u][v] = G[v][u] = 1; 65 if(u < v) edge[u][id[u]++] = v; 66 else edge[v][id[v]++] = u; 67 dig[u]++; dig[v]++; 68 } 69 for(int i = 1; i <= n-s+1; i++) { 70 if(dig[i] < s - 1) continue; 71 tmp[1] = i; 72 dfs(2); 73 } 74 printf("%d\n", ret); 75 } 76 return 0; 77 }