hdu5917(ramsey定理)
阿新 • • 發佈:2018-11-16
題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=5917
思路:Ramsey定理的通俗表述: 6 個人中至少存在3人相互認識或者相互不認識。所以對於大於6的子集都是滿足條件的,組合數算一下就好,對於小於6的子集,最多是n的5次方,直接暴力。
#include <cstdio> #include <cstdlib> #include <cstring> #include <bitset> #include <cmath> #include <cctype> #include <iostream> #include <algorithm> #include <string> #include <vector> #include <queue> #include <map> #include <set> #include <sstream> #include <iomanip> using namespace std; typedef long long ll; typedef unsigned long long ull; const ll inff = 0x3f3f3f3f3f3f3f3f; #define FOR(i,a,b) for(int i(a);i<=(b);++i) #define FOL(i,a,b) for(int i(a);i>=(b);--i) #define REW(a,b) memset(a,b,sizeof(a)) #define inf int(0x3f3f3f3f) #define si(a) scanf("%d",&a) #define sl(a) scanf("%lld",&a) #define sd(a) scanf("%lf",&a) #define ss(a) scanf("%s",a) #define mod ll(1e9+7) #define pb push_back #define eps 1e-6 #define lc d<<1 #define rc d<<1|1 #define Pll pair<ll,ll> #define P pair<int,int> #define pi acos(-1) ll c[58][58],n,m,ans,ma[58][58]; void init() { c[0][0]=1; FOR(i,1,50) FOR(j,0,i) { if(j==0||j==i) c[i][j]=1; else c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod; } } bool as(int x,int y,int z) { int s=0; s+=ma[x][y]; s+=ma[x][z]; s+=ma[z][y]; return (s==3||s==0)?1:0; } int main() { cin.tie(0); cout.tie(0); int t,x,y,res=1; cin>>t; init(); while(t--) { sl(n),sl(m); ans=0;REW(ma,0); if(n>=6) FOR(i,6,n) ans=(ans+c[n][i])%mod; FOR(i,1,m) { si(x),si(y); ma[x][y]=ma[y][x]=1; } if(n>=3) { FOR(i,1,n) FOR(j,i+1,n) FOR(k,j+1,n) { if(as(i,j,k)) ans++; } } if(n>=4) { FOR(i,1,n) FOR(j,i+1,n) FOR(k,j+1,n) FOR(kk,k+1,n) { if(as(i,j,k)||as(i,j,kk)||as(i,k,kk)||as(k,j,kk)) ans++; } } if(n>=5) { FOR(i,1,n) FOR(j,i+1,n) FOR(k,j+1,n) FOR(kk,k+1,n) FOR(kkk,kk+1,n) { if(as(i,j,k)||as(i,j,kk)||as(i,j,kkk)||as(i,k,kk)||as(j,kk,kkk) ||as(i,k,kkk)||as(i,kk,kkk)||as(j,k,kk)||as(j,k,kkk)||as(kkk,k,kk)) ans++; } } printf("Case #%d: %lld\n",res++,ans%mod); } return 0; }