[清华集训2012] 串珠子
[清华集训2012] 串珠子
题意
给定
有
求有多少种方案使得整张图连通。
思路
注意到
定义
即
定义
其中
即枚举不连通的情况减去,枚举不连通的子集,
不连通子集连边的方案数乘上补集连通的方案数就是总方案数。
实现时注意固定
这里解释一下为什么是
这个转移方程本质上是把图分成两个互不连通的部分,
如果转移方程是第二种,就会出现重复,如下图。
这两种图本质相同,但由于没有限制一部分必须连通,就会被统计两遍。
所以必须限制一部分连通才能不重复。
因为我们固定了一个点和自己连通,如果交换
答案为
代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 20;
int n, c[N][N];
ll f[1 << N], g[1 << N];
const int mod = 1e9 + 7;
int main() {
cin >> n;
for (int i = 0; i < n; i ++)
for (int j = 0; j < n; j ++)
cin >> c[i][j];
for (int i = 0; i < (1 << n); i ++) {
g[i] = 1;
for (int j = 0; j < n; j ++)
if (i >> j & 1) for (int k = j + 1; k < n; k ++)
if (i >> k & 1)
g[i] = g[i] * (c[j][k] + 1) % mod;
}
for (int i = 0; i < (1 << n); i ++) {
int I = i ^ (i & (-i));
f[i] = g[i];
for (int j = I; j; j = (j - 1) & I) {
f[i] = f[i] - g[j] * f[i ^ j];
f[i] = (f[i] % mod + mod) % mod;
}
}
cout << f[(1 << n) - 1] << "\n";
return 0;
}
本文来自博客园,作者:maniubi,转载请注明原文链接:https://www.cnblogs.com/maniubi/p/18419322,orz
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!