HDU5952 Counting Cliques (暴力深搜+剪枝) (2016ACM/ICPC亚洲赛区沈阳站 Problem E)
题目链接:传送门
题目:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
Counting Cliques Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 4879 Accepted Submission(s): 1747 Problem Description A clique is a complete graph, in which there is an edge between every pair of the vertices. Given a graph with N vertices and M edges, your task is to count the number of cliques with a specific size S in the graph. Input The first line is the number of test cases. For each test case, the first line contains 3 integers N,M and S (N ≤ 100,M ≤ 1000,2 ≤ S ≤ 10), each of the following M lines contains 2 integers u and v (1 ≤ u < v ≤ N), which means there is an edge between vertices u and v. It is guaranteed that the maximum degree of the vertices is no larger than 20. Output For each test case, output the number of cliques with size S in the graph. Sample Input 3 4 3 2 1 2 2 3 3 4 5 9 3 1 3 1 4 1 5 2 3 2 4 2 5 3 4 3 5 4 5 6 15 4 1 2 1 3 1 4 1 5 1 6 2 3 2 4 2 5 2 6 3 4 3 5 3 6 4 5 4 6 5 6 Sample Output 3 7 15
题目大意:
给定一个有N个点,M条边的图,求有S个点的完全子图的数量。
(N ≤ 100,M ≤ 1000,2 ≤ S ≤ 10)
思路:
一个个点加入完全子图,大小达到S时ans++。
纯暴力好像会在4000ms上下徘徊,随便剪一下就过了。
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; const int MAX_N = 1e2 + 5; const int MAX_M = 1e3 + 5; int N, M, S; int ans; bool edge[MAX_N][MAX_N]; vector <int> Edge[MAX_N]; int vis[MAX_N]; int read() { int res = 0; char ch = getchar(); while (!isdigit(ch)) ch = getchar(); while (isdigit(ch)) { res *= 10; res += ch - '0'; ch = getchar(); } return res; } void dfs(int dep, int u) { if (Edge[u].size() < S-1) return; if (S-dep + u > N) return; if (dep == S) { ans++; return; } int Elen = Edge[u].size(); for (int i = 0; i < Elen; i++) { int v = Edge[u][i]; if (v < u) continue; if (Edge[v].size() < dep) continue; bool ok = true; for (int j = 1; j <= dep; j++){ int w = vis[j]; if (!edge[v][w]) { ok = false; break; } } if (ok) { vis[dep+1] = v; dfs(dep+1, v); } } } void addEdge(int u, int v) { edge[u][v] = edge[v][u] = true; Edge[u].push_back(v); Edge[v].push_back(u); } int main() { int T; cin >> T; while (T--) { N = read(); M = read(); S = read(); for (int i = 1; i <= N; i++) { Edge[i].clear(); for (int j = 1; j <= N; j++) edge[i][j] = false; } int u, v; for (int i = 1; i <= M; i++) { u = read(); v = read(); addEdge(u, v); } ans = 0; for (int i = 1; i <= N; i++) { vis[1] = i; dfs(1, i); } printf("%d\n", ans); } return 0; }