首页 > 技术文章 > 【BZOJ2560】串珠子

yinwuxiao 2018-07-16 15:02 原文

题解:

跟n个点有标号的无向连通图个数几乎一模一样

直接上代码了

代码:

 

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define IL inline
#define rint register ll
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
const ll N=30;
const ll mo=1e9+7;
ll n,a[N][N],f[1<<17],g[1<<17];
ll js2(ll x,ll y)
{
  x*=y;
  x%=mo;
  x=(x+mo)%mo;
  return(x);
}
ll js1(ll x,ll y)
{
  x+=y;
  x%=mo;
  x=(x+mo)%mo;
  return(x);
}
int main()
{
  freopen("1.in","r",stdin);
  freopen("1.out","w",stdout);
  ios::sync_with_stdio(false);
  cin>>n;
  rep(i,1,n)
    rep(j,1,n)
      cin>>a[i][j],a[i][j]++;
  f[0]=1;
  rep(i,1,(1<<n)-1)
  {
    ll ans;
    rep(j,1,n) 
    if ((i>>(j-1))&1)
    {
      ans=j;
      break;
    }
    f[i]=f[i^(1<<(ans-1))]; 
    rep(j,1,n) if (((i>>(j-1))&1)&&ans!=j) f[i]=js2(f[i],a[ans][j]); 
  }
  rep(i,1,(1<<n)-1)
    if (i&1)
    {
      for (ll j=i;j;j=(j-1)&i)
        if ((j&1)&&(j!=i))
          g[i]=js1(g[i],js2(f[j]-g[j],f[i^j]));
    }
  cout<<js1(f[(1<<n)-1],-g[(1<<n)-1]);
  return 0;
}

 

推荐阅读