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; }