整理的算法模板合集: ACM模板

点我看算法全家桶系列!!!

实际上是一个全新的精炼模板整合计划


Luogu P4336 [SHOI2016]黑暗前的幻想乡(容斥,矩阵树定理)

Problem

n≤17,P=109+7n\le 17, P = 10^9+7n≤17,P=109+7

Solution

题目就是要求由 n−1n-1n−1 个公司每个公司一条边建成的生成树的方案数。

显然求生成树的方案数,我们直接用矩阵树定理计算即可。

现在考虑满足 每个公司都只负责一条边的方案数 如何计算。

显然有:n≤17+计数问题=容斥n\le 17 + 计数问题 = \text{容斥}n≤17+计数问题=容斥

我们可以先用矩阵树定理计算 n−1n-1n−1 个公司包含的所有边集的生成树的个数,显然这里算出来的生成树,不一定 n−1n-1n−1 个公司都参与了建设,我们用容斥原理减去不合法的即可。

显然就是枚举有多少个公司没有参与建设,然后利用容斥原理奇加偶减,答案减去容斥原理计算出的结果,变成奇减偶加。

我们设 g(S)g(S)g(S)为最终的答案,即全集 SSS 全部被覆盖的情况的方案数。

f(S)f(S)f(S) 为公司恰好仅为 SSS 的方案。

显然有:

g(S)=∑T⊆Sf(T)g(S)=\sum\limits_{T\subseteq S}f(T)g(S)=T⊆S∑​f(T)

根据子集反演可得:

f(S)=∑T⊆S(−1)∣S∣−∣T∣g(T)f(S)=\sum\limits_{T\subseteq S}(-1)^{\left|S\right|-\left|T\right|}g(T)f(S)=T⊆S∑​(−1)∣S∣−∣T∣g(T)

即答案就是所有生成树的方案数,减去 111 个公司没有参与,由剩下的 n−2n-2n−2 个公司建成的生成树的个数,加上 222 个公司没有参与,由剩下的 n−3n-3n−3 个公司建成的生成树的个数,减去 333 个公司没有参与,由剩下的 n−4n-4n−4 个公司建成的生成树的个数 ⋯\cdots⋯

我们可以通过二进制枚举来枚举具体选择了那几个公司的边,处理出此时的基尔霍夫矩阵,然后直接利用矩阵树定理高斯消元 O(n3)O(n^3)O(n3) 计算代数余子式的行列式即可。

注意我们矩阵树定理计算的时候是可以处理重边的,所以如果一条边被多个公司覆盖,就把它当成重边即可,这样都当成重边算,最后减下来是没有重边的。

Time

O(2n×n3log⁡P)O(2^{n}\times n^3\log P)O(2n×n3logP)

Code

// Problem: P4336 [SHOI2016]黑暗前的幻想乡
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P4336
// Memory Limit: 250 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
#define int long long
using namespace std;const int N = 100 + 7, M = 1e5 + 7, mod = 1e9 + 7;int n, m[M], s, t, k, ans, a[N][N];
int siz[M];
int u[N][N], v[N][N];int qpow(int a, int b)
{int res = 1;while(b) {if(b & 1) res = res * a % mod;a = a * a % mod;b >>= 1;}return res;
}int guass2(int n)// 辗转相除 = TLE
{int det = 1;for (int i = 2; i <= n; ++ i) {for (int j = i + 1; j <= n; ++ j) {while(a[j][i]) {int t = a[i][i] / a[j][i];for (int k = i; k <= n; ++ k)a[i][k] = (a[i][k] - t * a[j][k] + mod) % mod;swap(a[i], a[j]);det = -det;} }det = (det * a[i][i]) % mod;if(det == 0) return 0;}return (det + mod) % mod;
}int guass(int n)// 求逆元 = AC
{int det = 1;for (int i = 2; i <= n; ++ i) {for (int j = i; j <= n; ++ j) {if(a[i][j]) {swap(a[i], a[j]);if(i != j) det = mod - det;break;}}int inv = qpow(a[i][i], mod - 2);for (int j = i + 1; j <= n; ++ j) {if(a[j][i]) {int tmp = a[j][i] * inv % mod;for (int k = i; k <= n; ++ k) {a[j][k] = (a[j][k] - a[i][k] * tmp % mod + mod) % mod;}}}}for (int i = 2; i <= n; ++ i)det = det * a[i][i] % mod;return det;
}signed main()
{scanf("%lld", &n); for (int i = 1; i <= n - 1; ++ i) {scanf("%lld", &m[i]);for (int j = 1; j <= m[i]; ++ j) {scanf("%lld%lld", &u[i][j], &v[i][j]);int x = u[i][j], y = v[i][j];a[x][x] ++ ;a[y][y] ++ ;a[x][y] = (a[x][y] + mod - 1) % mod;a[y][x] = (a[y][x] + mod - 1) % mod;}} ans = guass(n);for (int i = 1; i <= (1 << (n - 1)) - 1; ++ i) {for (int j = 1; j <= n; ++ j) for (int k = 1; k <= n; ++ k) a[j][k] = 0;int cnt = 0;int tmp = i, j;for (j = 1; tmp; tmp >>= 1, ++ j) {if((tmp & 1) == 0) continue;cnt ++ ; for (int k = 1; k <= m[j]; ++ k) {int x = u[j][k], y = v[j][k];a[x][x] ++ ;a[y][y] ++ ;a[x][y] = (a[x][y] + mod - 1) % mod;a[y][x] = (a[y][x] + mod - 1) % mod;}}if(cnt == n - 1) continue;ans = (ans - ((((n - 1) - cnt) & 1) ? 1 : -1) * guass(n) + mod) % mod;}printf("%lld\n", ans);return 0;
}

Luogu P4336 [SHOI2016]黑暗前的幻想乡(容斥,矩阵树定理,子集反演)相关推荐

  1. 【BZOJ4596】[Shoi2016]黑暗前的幻想乡 容斥+矩阵树定理

    [BZOJ4596][Shoi2016]黑暗前的幻想乡 Description 幽香上台以后,第一项措施就是要修建幻想乡的公路.幻想乡有 N 个城市,之间原来没有任何路.幽香向选民承诺要减税,所以她打 ...

  2. [BZOJ4596][Shoi2016]黑暗前的幻想乡-Matrix Tree 矩阵树定理

    黑暗前的幻想乡 Description 四年一度的幻想乡大选开始了,最近幻想乡最大的问题是很多来历不明的妖怪涌入了幻想乡,扰乱了幻想乡昔日的秩序.但是幻想乡的建制派妖怪(人类)博丽灵梦和八云紫等人整日 ...

  3. P4336 [SHOI2016]黑暗前的幻想乡

    题目 P4336 [SHOI2016]黑暗前的幻想乡 做法 每种颜色恰好一条边,有点难处理啊 根据套路,数据范围这么小,容斥一下所有的情况就可以了 对每种颜色进行状压,表这次只能选这些颜色,做\(n- ...

  4. 洛谷 P4336 [SHOI2016] 黑暗前的幻想乡 题解

    前置芝士 Kirchhoff 矩阵树定理 Kirchhoff矩阵树定理解决了一个问题:对于一个确定的无向图,其究竟有多少个生成树? 对于一个无向图,我们拥有其邻接矩阵 A\bf{A}A. 这里的邻接矩 ...

  5. BZOJ4596:[SHOI2016]黑暗前的幻想乡——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4596 https://www.luogu.org/problemnew/show/P4336#su ...

  6. SHOI2016 黑暗前的幻想乡

    题目链接:戳我 幻想乡是个什么东西??(逃 矩阵树定理+容斥 就是设\(dp[i]\)表示至多i个公司修建道路,那么我们有\(ans=dp[n-1]-dp[n-2]+dp[n-3]......\)ba ...

  7. ●BZOJ 4596 [Shoi2016]黑暗前的幻想乡

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4596 题解: 容斥,矩阵树定理,矩阵行列式 先说说容斥:(一共有 N-1个公司) 令 f[i ...

  8. bzoj 4596: [Shoi2016]黑暗前的幻想乡

    这个题貌似奶了一口trump,,, 本来看到一个公司一条边,而且N是那么科学,肯定要容斥了,然后蛋疼的想应该怎么求生成树.. 本来一开始乱说了个矩阵树定理,然而忘了,就像奇奇怪怪的东西了..然并卵,正 ...

  9. [luogu3244 SHOI2016] 黑暗前的幻想乡(容斥原理+矩阵树定理)

    传送门 Description 给出 n 个点和 n−1 种颜色,每种颜色有若干条边.求这张图多少棵每种颜色的边都出现过的生成树,答案对 109+7 取模. Input 第一行包含一个正整数 N(N& ...

最新文章

  1. 第3关:单链表循环队列
  2. 批量图片压缩工具:JPGCompact 2.0绿色版
  3. 【阿里云API】 阿里云API调用的若干说明
  4. 像个字段相减绝对值_【高考数学】33个知识点+66个易混点大整合
  5. win7计算机怎么找管理员,Win7系统Administrator不见了怎么解决?
  6. 是什么的简称_被简称为“中大”的大学,为什么没有别的大学和它争名字?
  7. 培养这10个习惯,你就离UNIX高手更进一步了
  8. mysql 报错3534_win7下安装MYSQL报错:MYSQL 服务无法启动的3534问题
  9. php如何判断是否为json格式,php如何判断是否为json数据(格式)
  10. linux git ssh 配置文件,git bash配置ssh 登录 Linux的方法
  11. 树莓派3B 开启串口
  12. 格雷码Gray Code详解
  13. unity 中画布随相机视野实时变化
  14. 深度学习入门:基于Python的理论与实现——第一章Python入门
  15. 预充电电路工作原理_电池管理系统中的高压预充电电路原理解析
  16. pdf文件太大如何压缩变小一点?
  17. 2021暑假Leetcode刷题——Two Pointers(3)
  18. ftp服务器搭建随手记
  19. 多多视频如何快速涨粉(赚钱变现)
  20. 非洲秃鹫优化算法:求解全局优化问题的一种新的自然启发元启发式算法(Matlab代码实现)

热门文章

  1. OpenCV视频分析背景提取与前景提取
  2. 机器视觉系统原理及学习策略
  3. 机器视觉系统设计关键:成像基准
  4. 假如计算机是中国人发明的,那代码应该这么写
  5. 自动驾驶的视觉感知包括哪些内容?
  6. 【从零学习OpenCV 4】安装过程中问题解决方案
  7. 搭建hbase1.2.5完全分布式集群
  8. 高盛:人工智能生态报告 最全AI产业盘点
  9. vsftp和nfs服务
  10. RMAN 与control文件和spfile文件的备份