谎言重复一千次就变成真理 回|

Day_Dreamer_D

园龄:3年6个月粉丝:3关注:16

2022-11-04 18:04阅读: 62评论: 0推荐: 0

矩阵树定理学习笔记 & 洛谷 P4111 [HEOI2015]小 Z 的房间 题解

矩阵树定理

拉普拉斯矩阵

无边权

设无向图 Gn 个结点,则拉普拉斯矩阵 L 是一个 n×n 的矩阵,满足:

  • Li,i(iG) 的值为结点 i 的度数。
  • Li,j(i,jG,ij) 的值为结点 i,j 之间相连的边数的相反数。

如下图:

Graph

它的拉普拉斯矩阵

L=[2110131111310112]

有边权

推广一下:

  • Li,i(iG) 的值为所有与结点 i 相连的边权和。
  • Li,j(i,jG,ij) 的值为边 ij 的权的相反数。

定理内容

严谨的定理内容参见 OI Wiki 上对矩阵树定理的叙述。

通俗来说,把拉普拉斯矩阵去掉任意的一行一列,得到的矩阵的行列式就是原图的生成树数量(带权就是所有生成树中边的积的和)。

证明

关于这个我也不会,可以去看文末《矩阵树定理(Matrix-tree Theorem)笔记》。

求矩阵的行列式

行列式有如下性质:

  • 将矩阵的两行交换,其行列式变成相反数。
  • 将矩阵的一行加上(另一行乘一个数),其行列式不变。
  • 三角矩阵的行列式为对角线的乘积。

利用这三条性质可以把矩阵变成三角矩阵,从而求出行列式。

比如刚才的矩阵(去掉第一行和最后一列):

[211131113]

将第一行乘 12,加到第二、第三行去,再将第二行乘 35,加到第三行去,最终形成的三角矩阵:

[211052320085]

则其行列式为 2×52×85=8

而原图恰好有 8 个生成树:

Spanning Tree

代码

回到本题,不难发现是道裸的矩阵树定理,时间复杂度 O(n3m3)

/*
* Title: P4111 [HEOI2015]小 Z 的房间
* Source: 洛谷
* URL: https://www.luogu.com.cn/problem/P4111
* Author: Steven_lzx
* Command: -std=c++23 -Wall -fno-ms-extensions
* Date: 2022.11.4
*/
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int MOD=1e9;
int n,m,cnt,ans=1,laplace[100][100]/*拉普拉斯矩阵*/,id[20][20],l;
char ch[20][20];
void change(int x,int y)
{
laplace[x][x]++;
laplace[y][y]++;
laplace[x][y]--;
laplace[y][x]--;
return;
}
signed main()
{
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
do
scanf("%c",&ch[i][j]);
while(ch[i][j]!='.'&&ch[i][j]!='*');
if(ch[i][j]=='.')
id[i][j]=++cnt;//编号
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(ch[i][j]=='.'&&ch[i+1][j]=='.')
change(id[i][j],id[i+1][j]);
if(ch[i][j]=='.'&&ch[i][j+1]=='.')
change(id[i][j],id[i][j+1]);
}
}
cnt--;
for(int i=1;i<cnt;i++)
{
for(int j=i+1;j<=cnt;j++)
{
while(laplace[j][i])
{
l=laplace[i][i]/laplace[j][i];
for(int k=1;k<=cnt;k++)
laplace[i][k]=(laplace[i][k]-laplace[j][k]*l%MOD+MOD)%MOD;
for(int k=1;k<=cnt;k++)
swap(laplace[i][k],laplace[j][k]);
ans*=-1;
}
}
}
for(int i=1;i<=cnt;i++)
ans=(ans*laplace[i][i]%MOD+MOD)%MOD;
printf("%lld\n",ans);
return 0;
}

参考资料

本文作者:Day_Dreamer_D's Blog

本文链接:https://www.cnblogs.com/2020gyk080/p/16858678.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Day_Dreamer_D  阅读(62)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起