题目大意:团的定义就是,团内的所有点,两两之间各有一条边,团的大小就是点的个数。现给你一个n个点,m条边的图。问,该图中有多少点的个数为s的团。
(题目保证每个点的度数不超过20,n<=100, m<=1000, s<=10)
思路:由于度数不超过20,那么最多就是C20取9,于是我们暴力枚举一下就好了。然后在代码中,我规定,邻接表G[U]里面的元素,都是u<v的。
//看看会不会爆int!数组会不会少了一维! //取物问题一定要小心先手胜利的条件 #include <bits/stdc++.h> using namespace std; #pragma comment(linker,"/STACK:102400000,102400000") #define LL long long #define ALL(a) a.begin(), a.end() #define pb push_back #define mk make_pair #define fi first #define se second #define haha printf("haha ") const int maxn = 500 + 5; vector<int> G[maxn]; bool atlas[maxn][maxn]; int a[maxn]; int n, m, s; int dfs(int u, int pos, int cnt, int s){ if (cnt == s) { return 1; } int ans = 0; for (int i = pos; i < G[u].size(); i++){ int v = G[u][i]; bool flag = true; for (int j = 1; j <= cnt; j++){ if (!atlas[a[j]][v]) {flag = false; break;} } if (!flag) continue; a[cnt + 1] = v; ans += dfs(u, i + 1, cnt + 1, s); } return ans; } int solve(){ vector<int> ds; for (int i = 1; i <= n; i++){ if (G[i].size() >= s - 1) ds.pb(i); } int ans = 0; for (int i = 0; i < ds.size(); i++){ int u = ds[i]; a[1] = u; for (int j = 0; j < G[u].size(); j++){ int v = G[u][j]; a[2] = v; ans += dfs(u, j + 1, 2, s); } } return ans; } int main(){ int t; cin >> t; while (t--){ scanf("%d%d%d", &n, &m, &s); for (int i = 1; i <= n; i++) G[i].clear(); memset(atlas, 0, sizeof(atlas)); for (int i = 1; i <= m; i++){ int u, v; scanf("%d%d", &u, &v); if (atlas[u][v]) continue; atlas[u][v] = 1, atlas[v][u] = 1; if (u > v) swap(u, v); G[u].pb(v); } printf("%d ", solve()); } return 0; }