[hdu 5917 Instability] ramsey定理
题目链接:[hdu 5917 Instability]
题意描述:有
N
个顶点,
解题思路:
先解释一下, Ramsey定理。
在组合数学上,拉姆齐(Ramsey)定理,又称拉姆齐二染色定理,是要解决以下的问题:要找这样一个最小的数 n ,使得
n 个人中必定有 k 个人相识或l 个人互不相识。那么 R(k,l)=n 。
Ramsey定理应用的一个通俗的例子【友谊定理】:世界上任意6个人中,总有3个人相互认识,或互相皆不认识。即 R(3,3)=6 。
关于 R(3,3)=6 的证明:请参考维基百科-拉姆齐定理
显然,当顶点个数
≥6
的时候,显然是满足条件的。直接求
C6n+C7n+…+Cnn
。
对于顶点个数为
3,4,5
的情况,单独考虑。暴力计算一下,复杂度也就
O(N5)
。
#include <bits/stdc++.h>
using namespace std;
typedef __int64 LL;
typedef pair<int, int> PII;
const int MAXN = 50 + 5;
const LL MOD = 1000000007;
int T, N, M, cas;
bool G[MAXN][MAXN];
LL ans, C[MAXN][MAXN];
void I() {
for(int i = 0; i < MAXN; i++) C[i][0] = 1;
for(int i = 1; i < MAXN; i++) {
for(int j = 1; j <= i; j++) {
C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % MOD;
}
}
}
bool check(int sz, int buf[]) {
int sum = 0;
for(int i = 0; i < sz; i++) {
for(int j = i + 1; j < sz; j++) {
for(int k = j + 1; k < sz; k++) {
if(G[buf[i]][buf[j]] && G[buf[j]][buf[k]] && G[buf[i]][buf[k]]) return true;
if(!G[buf[i]][buf[j]] && !G[buf[j]][buf[k]] && !G[buf[i]][buf[k]]) return true;
}
}
}
return false;
}
inline void F(const int& v) {
ans += v;
if(ans >= MOD) ans -= MOD;
}
void solve() {
int a[5];
for(a[0] = 1; a[0] <= N; a[0]++) {
for(a[1] = a[0] + 1; a[1] <= N; a[1]++) {
for(a[2] = a[1] + 1; a[2] <= N; a[2]++) {
if(check(3, a)) F(1);
for(a[3] = a[2] + 1; a[3] <= N; a[3]++) {
if(check(4, a)) F(1);
for(a[4] = a[3] + 1; a[4] <= N; a[4]++) {
if(check(5, a)) F(1);
}
}
}
}
}
}
int main() {
// freopen("input.txt", "r", stdin);
int u, v; I();
scanf("%d", &T); cas = 0;
while(T --) {
scanf("%d %d", &N, &M);
ans = 0;
if(N >= 6) {
for(int i = 6; i <= N; i++) {
F(C[N][i]);
}
}
memset(G, false, sizeof(G));
for(int i = 1; i <= M; i++) {
scanf("%d %d", &u, &v);
G[u][v] = G[v][u] = true;
}
solve();
printf("Case #%d: %I64d\n", ++ cas, ans);
}
return 0;
}