Instability [HDU - 5917 ](Ramsey定理)

Instability [HDU - 5917 ](Ramsey定理)

题面:

Long long ago, there was a prosperous kingdom which consisted of n cities and every two cites were connected by an undirected road.

However, one day a big monster attacked the kingdom and some roads were destroyed. In order to evaluate the influence brought by the catastrophe, the king wanted to know the instability of his kingdom. Instability is defined as the number of the unstable subset of {1, 2,⋯⋯,n}.

A set S is unstable if and only if there exists a set A such that \(A⊆S(|A|≥3)\) A is a clique or an independent set, namely that cites in A are pairwise connected directly or they are pairwise disconnected.

Archaeologist has already restored themroads that were not destroyed by the monster. And they want you to figure out the instability.

Since the answer may be tremendously huge, you are only required to write a program that prints the answer modulo 1000000007.

题意:

给你一个含有\(\mathit n\)个节点,\(m\)个边的无向图,

现在问你该无向图有多少个不稳定的子集\(S\),

一个集合被称为不稳定的当且仅当存在一个节点个数大于等于\(\text 3\)的子集,该子集为一个团(完全图)或者独立集。

思路:

解题关键:

拉姆齐(Ramsey)定理:

6 个人中至少存在3人相互认识或者相互不认识。

该定理等价于证明大于等于6个顶点的完全图的边只用红、蓝二色任意着色,必然至少存在一个红色边三角形,或蓝色边三角形。

知道该定理之后,那么所以该图节点个数大于等于\(\text 6\)的子集都是不稳定的,

那么我们可以把子集大小大于\(\text 2\)的所以集合个数\(ans_1\)减去\(3\leq|S|\leq5\) 的集合中稳定的即可。

\(3\leq|S|\leq5\)这部分我们可以通过枚举判断解决。

代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <bits/stdc++.h>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define chu(x)  if(DEBUG_Switch) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
#define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
#define du2(a,b) scanf("%d %d",&(a),&(b))
#define du1(a) scanf("%d",&(a));
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) { if (a == 0ll) {return 0ll;} a %= MOD; ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
ll poww(ll a, ll b) { if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a ;} a = a * a ; b >>= 1;} return ans;}
void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
inline long long readll() {long long tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') { fh = -1; } c = getchar();} while (c >= '0' && c <= '9') { tmp = tmp * 10 + c - 48, c = getchar(); } return tmp * fh;}
inline int readint() {int tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') { fh = -1; } c = getchar();} while (c >= '0' && c <= '9') { tmp = tmp * 10 + c - 48, c = getchar(); } return tmp * fh;}
void pvarr_int(int *arr, int n, int strat = 1) {if (strat == 0) {n--;} repd(i, strat, n) {printf("%d%c", arr[i], i == n ? '\n' : ' ');}}
void pvarr_LL(ll *arr, int n, int strat = 1) {if (strat == 0) {n--;} repd(i, strat, n) {printf("%lld%c", arr[i], i == n ? '\n' : ' ');}}
const int maxn = 1000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
#define DEBUG_Switch 0
int n;
int vis[55][55];
const ll mod = 1000000007;
bool check(int a, int b, int c)
{
    return (vis[a][b] + vis[a][c] + vis[c][b] == 3) || (vis[a][b] + vis[a][c] + vis[c][b] == 0);
}
bool check(int a, int b, int c, int d)
{
    return check(a, b, c) || check(a, b, d) || check(a, c, d) || check(b, c, d);
}
bool check(int a, int b, int c, int d, int e)
{
    return check(a, b, c, d) || check(a, b, c, e) || check(a, b, d, e) || check(a, c, d, e) || check(b, c, d, e);
}
int main()
{
#if DEBUG_Switch
    freopen("D:\\code\\input.txt", "r", stdin);
#endif
    //freopen("D:\\code\\output.txt","w",stdout);
    int t;
    t = readint();
    for (int cas = 1; cas <= t; ++cas) {
        n = readint();
        repd(i, 1, n) {
            repd(j, 1, n) {
                vis[i][j] = 0;
            }
        }
        int m = readint();
        repd(i, 1, m) {
            int x = readint();
            int y = readint();
            vis[x][y] = 1;
            vis[y][x] = 1;
        }
        ll ans = powmod(2ll, n, mod);
        ans = (ans - 1 - n + mod) % mod;
        ans = (ans  - n * (n - 1)/2 + mod) % mod;
        repd(i, 1, n)
        repd(j, i + 1, n)
        repd(k, j + 1, n) {
            if (!check(i, j, k)) {
                ans = (ans - 1 + mod) % mod;
            }
        }
        repd(i, 1, n)
        repd(j, i + 1, n)
        repd(k, j + 1, n)
        repd(z, k + 1, n) {
            if (!check(i, j, k, z)) {
                ans = (ans - 1 + mod) % mod;
            }
        }

        repd(i, 1, n)
        repd(j, i + 1, n)
        repd(k, j + 1, n)
        repd(z, k + 1, n)
        repd(w, z + 1, n) {
            if (!check(i, j, k, z, w)) {
                ans = (ans - 1 + mod) % mod;
            }
        }
        printf("Case #%d: %lld\n", cas, ans );
    }

    return 0;
}


posted @ 2020-09-30 00:58  茄子Min  阅读(286)  评论(0编辑  收藏  举报