1.题目链接。题目大意:给定一个无向图,求这个图有多少个点的集合,每个集合至少包含一个关于这个图的独立集或者团。并且集合的元素个数要大于等于3.
2。其实这个题目就是拉姆齐定理的应用,根据拉姆齐定理,6个人中一定有三个人互相认识或者互相不认识。这个认识和不认识就是我们这道题目中的边,然后更具这个题目我们可以算出来大于等于六个人一定满足的,总共的选择方案是(C(n,0)+C(n,1)....C(n,n)=pow(2,n),减去0到5.然后我们知道,小于三一定是没戏的,那么只有3,4,5了。这个时候我们直接暴力验证就行了。实际上也是比较容易的一个题目,只需要记得拉姆齐定理即可。
#include<bits/stdc++.h>
using namespace std;
#pragma warning(disable:4996)
const int N = 55;
const int mod = 1e9 + 7;
bool vis[N][N];
int n, m;
#pragma warning(disable:4996)
long long ans, c[N][N];
#define ll long long
void init() {
c[1][1] = c[0][1] = 1;
for (int i = 2; i <= n; i++)
for (int j = 0; j <= i; j++) {
if (j == 0) c[j][i] = 1;
else c[j][i] = (c[j][i - 1] + c[j - 1][i - 1]) % mod;
}
}
ll qpow(ll a, ll b)
{
ll res = 1;
while (b)
{
if (b & 1)
res = res * a%mod;
a = a * a%mod;
b >>= 1;
}
return res;
}
bool judge(int a, int b, int c) {
if (vis[a][b] && vis[a][c] && vis[b][c]) return true;
if (!vis[a][b] && !vis[a][c] && !vis[b][c]) return true;
return false;
}
bool judge(int a, int b, int c, int d) {
if (judge(a, b, c)) return true;
if (judge(a, b, d)) return true;
if (judge(a, c, d)) return true;
if (judge(b, c, d)) return true;
return false;
}
bool judge(int a, int b, int c, int d, int e) {
if (judge(a, b, c, d)) return true;
if (judge(a, b, c, e)) return true;
if (judge(a, c, d, e)) return true;
if (judge(b, c, d, e)) return true;
if (judge(a, b, d, e)) return true;
return false;
}
int main() {
int T;
scanf("%d", &T);
for (int I = 1; I <= T; I++) {
memset(vis, false, sizeof(vis));
scanf("%d%d", &n, &m);
for (int i = 0; i < m; i++) {
int ta, tb;
scanf("%d%d", &ta, &tb);
vis[ta][tb] = true;
vis[tb][ta] = true;
}
ans = 0;
if (n >= 6) {
init();
ans += qpow(2, n);
for (int i = 0; i < 6; i++) {
ans -= c[i][n];
ans += mod;
ans %= mod;
}
}
for (int i = 1; i <= n; i++)
for (int j = i + 1; j <= n; j++)
for (int k = j + 1; k <= n; k++)
if (judge(i, j, k))
ans++;
for (int i = 1; i <= n; i++)
for (int j = i + 1; j <= n; j++)
for (int k = j + 1; k <= n; k++)
for (int l = k + 1; l <= n; l++)
if (judge(i, j, k, l))
ans++;
for (int i = 1; i <= n; i++)
for (int j = i + 1; j <= n; j++)
for (int k = j + 1; k <= n; k++)
for (int u = k + 1; u <= n; u++)
for (int v = u + 1; v <= n; v++)
if (judge(i, j, k, u, v))
ans++;
ans %= mod;
printf("Case #%d: %lld\n", I, ans);
}
}