Matrix Tree Theorem LGV Lemma

news/2025/3/15 22:02:00/文章来源:https://www.cnblogs.com/Richardwhr/p/18282631

行列式基础:

约定:

  • \(\tau(P)\) 表示排列 \(P\) 的逆序对数量
  • \(det(A)=\sum\limits_{P}(-1)^{\tau(P)}\prod\limits_{i}^{n}A_{i,p_i}\)

引理:

引理1:对换(交换排列中任意两个元素)改变 \(\tau(P)\) 奇偶性:

考虑一次临项交换必定会使得逆序对数量 \(+-1\),一定会改变奇偶性。兑换 \((i,j),i<j\) 可以看成将 \(p_i\) 向右进行 \(i-j\) 次临项交换,将 \(a_j\) 向左进行 \(i-j-1\) 此临项交换。共进行了 \(2\times(i-j)-1\) 次,因此一定会改变排列逆序对数量的奇偶性。

引理2:行列交换,行列式值不变。

每一行只选一个,因此是对称的。

引理3:单位矩阵 \(I\) 的行列式的值为 \(1\)

除了对角线的排列,没得选。
类似的,上三角矩阵的行列式的值为 \(\prod\limits_{i=1}^{n}a_{i,i}\)

引理3:交换两行,行列式变号。

只考虑这两行,相当于对每个排列在这两行做一次对换,奇偶性改变,因此行列式的值会变号。

引理4:给某一行 \(\times t\),行列式 \(\times t\)

这个是比较显然的,每一行只选一个,因此可以给他提出来这个 \(t\)

引理5:行具有线性性

两个矩阵只有一行不一样,两个矩阵这一行对应相加之后的行列式的值=两个矩阵行列式的值相加。

还是每一行只选一个,因此对于某行中选了某个数的,给他展开之后就行了。

引理6:有两行一样的矩阵,行列式为 \(0\)

根据引理3,交换两行符号取反,但是矩阵没有边,相当于 \(det(A)=-det(A)\),即 \(det(A)=0\)

引理7:用矩阵的一行加上另一行的倍数,行列式不变。

假设是第 \(i\) 行加到第 \(j\) 行,构造一个第 \(j\) 行和第 \(i\) 行都是原矩阵中第 \(i\) 行的矩阵。根据引理6,这个矩阵的行列式为 \(0\)

给第 \(j\)\(\times k\),根据引理4,矩阵的行列式仍为 \(0\)

然后根据引理5,两个矩阵第 \(j\) 行对应相加之后的行列式等于之前两个行列式的值相加。

一个是零,一个是原矩阵,发现行列式的值就是原矩阵的。

高斯消元求行列式:

高斯消元其实只需要交换行,一行加上另一行的倍数,记录交换次数即可。

注意为了避免实数预算,使用辗转相减法做高斯消元,模板:

点击查看代码
int Gauss()
{int ans=1;for(int i=1;i<=n;i++){for(int j=i+1;j<=n;j++){while(a[j][i]!=0){int d=a[i][i]/a[j][i];for(int k=i;k<=n && d;k++) a[i][k]=(a[i][k]-a[j][k]*d%mod+mod)%mod;swap(a[i],a[j]),ans=-ans;}}}for(int i=1;i<=n;i++) ans=ans*a[i][i]%mod;return (ans+mod)%mod;
}

注意:对于一些有规律的行列式,可以考虑展开后求递推式。

定义去掉某些行列的剩余部分行列式为余子式,然后代数余子式就是乘上 \((-1)^{sumrem_i+sumrem_j}=(-1)^{sumdel_i+sumdel_j}\)

设删掉 \(i,j\) 的余子式称为 \(M_{i,j}\)

那么就有 \(D=\sum\limits_{j=1}^{m}(-1)^{i+j}M_{i,j} \times a_{i,j}\)

通过这个可以降阶。

更一般的表述是下面的定理:

拉普拉斯展开定理:在 \(n\) 阶行列式中,任意取定 \(k\) 行,由 \(k\) 行元素组成的所有 \(k\) 阶子式与代数余子式乘积之和等于行列式的值。

\(a_{i,j}\) 相当于为子式,\(M_{i,j} \times (-1)^{i+j}\) 相当于代数余子式。

[FJOI2007]轮状病毒 题解

矩阵树定理(Matrix-Tree Theorem)

矩阵树定理指出了一下事实:

定义 Kirchhoff 矩阵为:

\( K_{i,j}= \left\{ \begin{aligned} \sum\limits_{k!=i} w(i,k) & & i=j \\-w(i,j)& & i!=j \\ \end{aligned} \right. \)

其中 \(w(i,j)\) 表示边 \((i,j)\)\(i\) 的影响(边的方向视情况而定)

\(M\)\(K\) 删掉任意编号相同的行列后的矩阵 (\(n-1\) 阶子矩阵)

\(\sum\limits_{T}\prod\limits_{(u,v)\in T}w(u,v)=det(M)\)

其中删掉的行列是作为跟

应用

无向图生成树:

无论是求数量还是边权的乘积,都只用维护出 \(w\) 矩阵即可。

直接把无向边视为有向边,分别贡献 \(w()\) 即可。

有向图生成树

  • 内向树:\(w(i,j)\) 表示边 \(i\rightarrow j\)\(i\) 的贡献(出度)
  • 外向树:\(w(i,j)\) 表示边 \(i \leftarrow j\)\(i\) 的贡献(入度)

为啥是这样呢,考虑从删掉的一行一列考虑, 内向树跟没有出度,因此删掉他,统计他人的出度,外向树跟没有入度,统计他人入度。

例题与扩展:

  • [SHOI2016] 黑暗前的幻想乡

相当于统计每个恰好 \(0\) 人不参与的方案数,经典套路容斥,转化为钦定 \(i\) 人不参与,其余任意的方案数。

然后就是矩阵树定理模板了。

  • [SDOI2014] 重建

注意不选的边不选也是有概率的,不止和选了的边有关系。

考虑形式化列出要求的东西:

\[\sum\limits_{T}\prod\limits_{e \in T} p_e \prod\limits_{e\notin T}(1-p_e) \]

矩阵树定理能求的只能和选了的有关系,不选的部分我们用所有的除以选了的来处理(最关键点)

变成:

\[\sum\limits_{T}\prod\limits_{e \in T} p_e \times \frac{\prod\limits_{e}(1-p_e)}{\prod\limits_{e \in T}(1-p_e)} \]

化简:

\[\prod\limits_{e}(1-p_e) \sum\limits_{T}\prod\limits_{e \in T} \frac{p_e}{1-p_e} \]

对于 \(0,1\)\(eps\) 扰动一下即可。

  • [JSOI2010] 巨额奖金

最小生成树经典结论:

  • 对于不同的最小生成树,边权相同的边总是数量相同的。
  • 对于不同权值的边,互不影响,也就是加入每种权值得边贡献的连通性相同。

根据 Envy 的套路,想到了一个看起来很对的假做法:预处理出所有可能在最小生成树中边,然后直接跑矩阵树定理。

其实是错误的,因为这样对导致不同权值之间的边相互影响,使得某种边权的边贡献的连通性超过或不足自己本来应该贡献的。

hack数据:

点击查看代码
4
1 2 1
3 4 1
1 4 2
2 3 2

如果直接预处理,有可能连出两个 \(2\) 边权的生成树。

那怎么办呢:注意到每种边权的边贡献的连通性确定,也就是加入其他边权的任意树边后形成的连通块上,这种边权的边在做任意生成树,此时可以用矩阵树定理求出方案数。

由于不同权值的边互不影响,因此可以直接乘起来。

复杂度:设每种边权在 \(k\) 个联通块上做生成树,则总复杂度为 \(\sum\limits_{k} k^3 < n^3 (\sum\limits_{k} = n-1)\)

LGV 引理(LGV Lemma)

人话描述,证明省略。

定义与约定:

  • 给定 \(n\) 个起点 \(\{a_i\}\) 和终点 \(\{b_i\}\),以及一张包含这些点的 DAG,保证起点无入度,终点无出度。

  • 定义一条路径 \(P\) 的权值是经过所有边边权的乘积:\(W(P)=\prod\limits_{e \in P} w_e\)

  • 定义在排列上的路径 \(P_i\)\(\{P_i: a_i \rightarrow b_{p_i},p \in S_n\}\),

    其中 \(p\) 是这个路径组的排列,也就是起点对应的终点是谁。

  • 定义一个路径组 \(P: \{P_i, p \in S_n\, i=\{1,2,3,…,n\}\}\)

    如果这个路径组中不存在任何一个结点 \(u\),使得存在 \(i,j,i \not =j,u \in P_i,u \in P_j\),则称这个路径组为无交路径组,记为 \(P'\)

    路径组的权值为所有路径权值的乘积:\(W(P)=\prod\limits_{i=1}^{n}W(P_i)\)

  • 构造矩阵 \(A \in \mathbb{Z}^{n \times n}\),其中 \(A_{i,j}=W(a_i,b_j)\)

    其中 \(W(a_i,b_j)\) 就是从 \(a_i\)\(b_j\) 的所有路径 \(P\) 的权值和:\(\sum W(P)\)

LGV 引理的结论:

\[Det(A)=\sum\limits_{P'}(-1)^{\sigma(p)}W(P') \]

应用方法:

对于应用场景的要求:

  • 必须在 DAG 上;

  • 一般会要求所有路径无交。

对于最终结论的应用一般有两种:

  • 直接和你说是逆序对数量偶减奇的方案数;

  • 合法的不交路径唯一(没有逆序对),则此时路径的数量(权值)就是行列式的值。

对于细节分析和具体做法,确定 LGV 引理的三个要素:起点集合,终点集合,矩阵权值。

一般情况下要么在起点终点集合上做手脚,要么要求你快速算矩阵权值。

或者直接对着行列式的式子做排列的状压 Dp。

例题:

  • CF348D Turtles
    需要你自己确定一下起点和终点

  • [NOI2021] 路径交点
    需要思考正负号和逆序对的关系

  • [ABC216H] Random Robots
    没有终点怎么办

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/899402.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java学习四大名著:《Java核心技术 卷II:高级特性(原书第12版)》 | PDF免费下载

《Java核心技术 卷II:高级特性(原书第12版)》是Java学习的经典书籍,该书深入探讨了 Java 语言的高级功能,涵盖流与文件处理、并发编程、网络、数据库、JVM 调优等关键主题。适合有一定基础的开发者,帮助他们掌握高效编程技巧,优化性能,并深入理解 Java 生态系统,是进阶…

STM32CubeIDE 下载与安装教程(以 1.18.0 版本为例)

STM32CubeIDE 下载与安装教程(以 1.18.0 版本为例) 软件介绍 STM32CubeIDE 是 STMicroelectronics 提供的官方集成开发环境(IDE),专为 STM32 微控制器系列设计。它融合了 STM32CubeMX 和 Eclipse 的强大功能,提供了一个完整的开发环境,适用于嵌入式软件开发和调试。STM3…

【作业3】结对项目:实现一个自动生成小学四则运算题目的命令行程序

⭐成员:3223004473詹艺珏 and 3223004301吴梦琪 📎Github链接:https://github.com/Jue610/Jue610/tree/main/ArithProbelm这个作业属于哪个课程 23软件工程这个作业要求在哪里 【作业3】结对项目这个作业的目标 实现一个自动生成小学四则运算题目的命令行程序,培养团…

用ESP32做一个遥控机械臂

RC汽车机械臂只是一个有轮子的RC汽车。该机械臂是一个四自由度机械臂,这意味着它有四个运动部件。我使用mg90伺服电机,因为它们是金属的,但塑料sg90也应该工作。如下图所示。我使用了两个独立的电源,每个都由2S锂离子(Li-on)电池组成,一个用于MCU,另一个用于电机。这是为…

最小化安装Ubuntu

最小化安装 前言: 有时候需要搭建虚拟机,每一次都需要去找文章,搞小半天才能完成环境搭建 这一次写一篇文章记录一下,目的是以后能比较快速简单的搭建好环境 概要 最小化安装需要手动启用网卡 安装防火墙 ⇒ 打开某些端口确保ssh连接等 安装openssh-server openssh-client ⇒ …

愤怒的小鸟

Day 2025/2/20愤怒的小鸟剪切精灵图-改sprite mode为mutiple在sprite editor中slice设置弹弓与鸟的层级关系layer-player 鸟加springjoint组件-distance-0.3-autodistance关闭弹弓组件的一些基本属性:Distance:两点之间的固定距离(设定完有剩余的距离就是可拉伸的长度)Freq…

通过振动传感器,触发水的运动并将其转换为声音

“微挑战”是在巴塞罗那IAAC的“紧急未来设计硕士”课程中为期一周的工作坊。在这一周,我们有时间、空间和专业人士的支持来创建一个功能原型,它也可以是一个投机性的人工制品,有助于我们的个人研究和实践。这个原型应该基于迭代和使用:数字制造工具、生物制造、人工智能、…

单链表练习与重下AS

1.练习题:我的代码答案: /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* reverseList(struct ListNode* head) {struct ListNode dummpy;struct ListNode* tmp;dummpy.next=NULL;//引入临时…

pycharm连接autodl服务器

昨天听舍友说,他们第一个实验都跑完了,瞬间焦虑起来,原来落后这么多,完事昨天晚上7点开始看教程,配环境,看了好几个教程,每个教程都不一样竟然!然后问舍友,舍友说:你先知道你要跑什么项目,我说:我知道啊,我要做什么项目,想要什么结果,我都知道,项目和代码都有,…

shell脚本报错:test.sh: line 2: $\r: command not found

问题 在win上写好shell脚本,传到linux服务器运行调试的时候报错:test.sh: line 2: $\r: command not found 原因 这个错误是由于脚本文件的换行符问题引起的。Windows和Linux系统的换行符不同:Windows使用\r\n(回车+换行)。 Linux使用\n(换行)。脚本是在Windows上编辑的…

Power Apps 技术分享:制作响应式布局

前言Power Apps的一大优势就是可以不用多长时间,就能够配置出响应式布局。正文1.我们先新建一个屏幕,用来演示,如下图:2.添加一个横向容器,修改一下宽和高,根据屏幕尺寸自适应,如下图:逻辑应该蛮好理解的,就是用app的宽,减去当前控件距离顶部的距离的两倍,也就是上下…

day:22 python函数(5)——常用函数

一.len函数 print(len(列表名)) 定义:返回一个内容长度 案例: list=[1,2,3,4,5,6] print(len(list))二.abs 绝对值 print(abs(数值))输出绝对值 案例: a=-9 print(abs(a))三.id() print(id(表名)) 返回一个对象地址,返回对象唯一地址,标示一个整数 list=[1,2,3…