2016CCPC长春G (hdu 5917 Instability)

让你找一幅图里有多少点集含有三元环或者三个独立点。

由拉姆塞定理可知六个人中必有三个人认识或三个人都不认识,所以超过6的点集都算。

ans = pow(2,n) - C(n,i)   i属于[ 0 , 5 ]

r然后再暴力计算[ 3 , 5 ]的点集里哪些属于合法的即可。

 

 

 

#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define up rt,rt<<1,rt<<1|1
#define mem(x) memset(x,0,sizeof(x))
#define mem1(x) memset(x,-1,sizeof(x))
#define LMissher
using namespace std;
typedef long long ll;
typedef double db;
const int M = 1e2+7;
const double pi = acos(-1);
const int inf = 2147483647;
const ll mod = 1e9+7;

int _,n,m,cas=1;
int vis[M][M];
ll fac[M],inv[M];
ll C(int n,int m){
    return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
void init(){
    fac[0]=1;fac[1]=1;inv[1]=1; inv[0]=1;
    for (int i=2;i<M;i++)
    {
        fac[i]=fac[i-1]*i%mod;
        inv[i]=inv[mod%i]*(mod-mod/i)%mod;
    }
    for (int i=2;i<M;i++) inv[i]=inv[i-1]*inv[i]% mod;
}

ll quick_pow(ll p,ll k)
{
    ll res=1,tp=p;
    if(k<0) return 0;
    while(k){
        if(k&1) res=res*tp%mod;
        tp=tp*tp%mod;
        k>>=1;
    }
    return res;
}
int judge(int i,int j,int k){
    if(vis[i][j]&&vis[i][k]&&vis[j][k]) return 1;
    if(!vis[i][j]&&!vis[i][k]&&!vis[j][k]) return 1;
    return 0;
}
int judge1(int i,int j,int k,int l){
    if(judge(i,j,k)||judge(i,j,l)||judge(j,k,l)||judge(i,k,l)) return 1;
    return 0;
}
int judge2(int i,int j,int k,int l,int o){
    if(judge1(i,j,k,l)||judge1(i,j,k,o)||judge1(i,j,l,o)||judge1(j,k,l,o)||judge1(i,k,l,o)) return 1;
    return 0;
}
int main(){
    #ifdef LMissher
        freopen("1.in","r",stdin);
        freopen("1.out","w",stdout);
    #endif
    init();
    scanf("%d",&_);
    while(_--){
        scanf("%d%d",&n,&m);
        mem(vis);
        for(int i=1;i<=m;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            vis[u][v]=vis[v][u]=1;
        }
        ll ans=0;
        if(n>=6){
            ans=(ans+quick_pow(2,n))%mod;
            for(int i=0;i<6;i++)
                ans=(ans-C(n,i)+mod)%mod;
        }
        if(n>=3){
            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=(ans+1)%mod;
        }
        if(n>=4){
            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(judge1(i,j,k,l)) ans=(ans+1)%mod;
        }
        if(n>=5){
            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++)
                            for(int o=l+1;o<=n;o++)
                                if(judge2(i,j,k,l,o)) ans=(ans+1)%mod;
        }
        printf("Case #%d: %lld\n",cas++,ans);
    }
    return 0;
}
View Code

 

posted @ 2018-09-19 15:34  LMissher  阅读(272)  评论(0)    收藏  举报