[清华集训2012]串珠子

这个模型见过好几次了, 似乎很经典,就是一些点集形成的任意非连通图都可以表示为一个连通块和其它若干联通块。

#include <bits/stdc++.h>

const int mo = 1e9 + 7;

int g[17][17], n, lg[1<<16];
int all_[1<<16], ok_[1<<16], not_[1<<16];

int main() {
	scanf("%d", &n);
	for(int i=1; i<=n; ++i)
		for(int j=1; j<=n; ++j)
			scanf("%d", &g[i][j]);
	lg[0] = -1;
	for (int i=1; i<(1<<n); ++i) lg[i] = lg[i>>1] + 1;
	for(int S=1; S<(1<<n); ++S) {
		all_[S] = 1;
		for(int i=1; i<=n; ++i)
			for(int j=i+1; j<=n; ++j)
				if(((S>>(i-1))&1) && ((S>>(j-1))&1))
					all_[S] = (1ll * all_[S] * (g[i][j] + 1ll)) % mo;
		int p = lg[S&(-S)];
		for(int subS=(S-1)&S; subS; subS=(subS-1)&S) if((subS>>p)&1) {
			not_[S] += (1ll * ok_[subS] * all_[S ^ subS]) % mo;
			not_[S] %= mo;
		}
		ok_[S] = all_[S] - not_[S];
		ok_[S] = (ok_[S] % mo + mo) % mo;
	}
	std::cout << ok_[(1<<n)-1];
	return 0;
}
posted @ 2021-01-11 15:58  xwmwr  阅读(88)  评论(2编辑  收藏  举报