bzoj2560: 串珠子

觉得难度大可以先去做做poj1737

 

然后就成套路了

设f,g,h分别为点集联通的方案,不联通的方案,总方案

补集转化,算出g就好了。可以枚举子集,令这个子集联通,其他随便

为了不重复更新,固定最小的那个点转移就好了

 

觉得难度小可以做做bzoj3925

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const LL mod=1000000007;
const int maxn=20;
const int Bmax=71000;
int lowbit(int x){return x&-x;}

LL mp[maxn][maxn];
LL f[Bmax],g[Bmax],h[Bmax];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            scanf("%d",&mp[i][j]);
            
    int li=(1<<n)-1;
    for(int zt=1;zt<=li;zt++)
    {
        h[zt]=1;
        for(int i=1;i<=n;i++)
            for(int j=i+1;j<=n;j++)
                if((zt&(1<<i-1))&&(zt&(1<<j-1)))
                    h[zt]=h[zt]*(mp[i][j]+1)%mod;
        
        //.....inith.....
        
        int p=lowbit(zt);
        for(int ut=(zt-1)&zt;ut!=0;ut=(ut-1)&zt)
            if(ut&p)g[zt]=(g[zt]+f[ut]*h[zt^ut])%mod;
        f[zt]=((h[zt]-g[zt])%mod+mod)%mod;
    }
    printf("%lld\n",f[li]);
    
    return 0;
}

 

posted @ 2019-01-21 08:14  AKCqhzdy  阅读(126)  评论(0编辑  收藏  举报