行列式:

参考

oi-wiki

定义

对于一个\(n*n\)的矩阵A行列式取值(标量)

\(det(A)=|A|=\sum\limits_p(-1)^{\tau(p)}\prod\limits_{i=1}^na_{i,p_i}\)

\(\tau(p)\)即排列\(p\)的逆序对个数。

性质

证明后面再补

1.\(|A|=|A^T|\),即排列是按排列p下表为行的行列式等同于排列p下标为列的得到的行列式。

2.交换两行(列),行列式取相反数

3.把一个矩阵的一行(列)的值全部乘一个常数加到另一行(列)上,行列式值不变。

求解

看看性质3,是不是很像高斯消元。

然后高斯消元后面得到的是一个倒三角矩阵。(除了这个斜下对角线排列,其它排列都含零)

画画图可以发现,最后答案是\(\prod\limits_{i=1}^na_{i,i}\)。中途注意维护一下交换两行带来的正负的变化。

ps.下面这道题消元用的是辗转相减(除),因为p不一定是质数,不一定能求逆元。

code【模板】行列式求值:

#include<bits/stdc++.h>
using namespace std;
const int N=605;
int n,p,a[N][N];
void Gauss() {
int opt=1;
for(int i=1;i<=n;i++) {
for(int j=i+1;j<=n;j++) {
while(a[i][i]) {
int d=a[j][i]/a[i][i];
for(int k=1;k<=n;k++) {a[j][k]-=1ll*a[i][k]*d%p;a[j][k]%=p;}
opt=-opt;swap(a[i],a[j]);
}
opt=-opt;swap(a[i],a[j]);
}
}
int ans=opt;
for(int i=1;i<=n;i++)ans=1ll*ans*a[i][i]%p;
printf("%d",(ans+p)%p);
}
int main() {
scanf("%d%d",&n,&p);
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) {scanf("%d",&a[i][j]);}
Gauss();
return 0;
}

矩阵树定理

求解的是一个图中的所有生成树边权积的和

  • 无向图

    定义Laplace矩阵L为:

    \(L(G)=D(G)-A(G)\)

    其中\(D(G)\)为度数矩阵。每个\(D_{i,i}=deg[i]\)其余行列不等的值为\(0\)。\(A(G)\)为邻接矩阵。

    \(|L(G)|\)即为答案。

    ps.自环不计入
  • 有向图

    出树(从根往外连):\(D\)为\(in[]\)入度

    入树(从外往根连):\(D\)为\(out[]\)出度

    特别的:生成树的个数\(t(G)\)即把边权赋为1,这样每个生成树的权值就是1。
  • code【模板】Matrix-Tree 定理:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=305;
const int mod=1e9+7;
ll a[N][N],mul,opt=1;
int n,m,t;
ll ksm(ll a,ll b) {ll res=1;for(;b;b>>=1,a=a*a%mod)if(b&1)res=res*a%mod;return res;}
void Gauss() {
opt=1;
for(int i=2;i<n;i++) {
int r=i;
while(r<=n&&!a[r][i]) r++;
if(r>n) {continue;}
if(r!=i) {swap(a[r],a[i]);opt=-opt;}
for(int j=i+1;j<=n;j++) {
ll d=a[j][i]*ksm(a[i][i],mod-2)%mod;
for(int k=2;k<=n;k++) a[j][k]-=a[i][k]*d,a[j][k]%=mod;
}
}
mul=opt;
for(int i=2;i<=n;i++)mul=mul*a[i][i]%mod;
mul=(mul+mod)%mod;
printf("%lld\n",mul);
}
int main() {
// freopen("data.in","r",stdin);
scanf("%d%d%d",&n,&m,&t);
for(int i=1;i<=m;i++) {
int u,v,w;scanf("%d%d%d",&u,&v,&w);
a[u][v]=(a[u][v]-w)%mod;a[v][v]=(a[v][v]+w)%mod;
if(!t) {a[v][u]=(a[v][u]-w)%mod;a[u][u]=(a[u][u]+w)%mod;}
}
Gauss();
return 0;
}

BEST 定理

设\(G\)是有向欧拉图,求欧拉回路个数

\(ec(G)=t_{out(G)}*\prod\limits_{v \in V}(deg[v]-1)!\)

ps.欧拉图即含欧拉回路的图,满足\(in[v]=out[v]\),而且选哪个根都一样。

行列式&矩阵树定理的更多相关文章

  1. 矩阵树定理&BEST定理学习笔记

    终于学到这个了,本来准备省选前学来着的? 前置知识:矩阵行列式 矩阵树定理 矩阵树定理说的大概就是这样一件事:对于一张无向图 \(G\),我们记 \(D\) 为其度数矩阵,满足 \(D_{i,i}=\ ...

  2. LOJ #6044 -「雅礼集训 2017 Day8」共(矩阵树定理+手推行列式)

    题面传送门 一道代码让你觉得它是道给初学者做的题,然鹅我竟没想到? 首先考虑做一步转化,我们考虑将整棵树按深度奇偶性转化为一张二分图,即将深度为奇数的点视作二分图的左部,深度为偶数的点视作二分图的右部 ...

  3. [spoj104][Highways] (生成树计数+矩阵树定理+高斯消元)

    In some countries building highways takes a lot of time... Maybe that's because there are many possi ...

  4. BZOJ 2467: [中山市选2010]生成树(矩阵树定理+取模高斯消元)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2467 题意: 思路:要用矩阵树定理不难,但是这里的话需要取模,所以是需要计算逆元的,但是用辗转相减会 ...

  5. 2018.09.16 spoj104Highways (矩阵树定理)

    传送门 第一次写矩阵树定理. 就是度数矩阵减去邻接矩阵之后得到的基尔霍夫矩阵的余子式的行列式值. 这个可以用高斯消元O(n3)" role="presentation" ...

  6. 【算法】Matrix - Tree 矩阵树定理 & 题目总结

    最近集中学习了一下矩阵树定理,自己其实还是没有太明白原理(证明)类的东西,但想在这里总结一下应用中的一些细节,矩阵树定理的一些引申等等. 首先,矩阵树定理用于求解一个图上的生成树个数.实现方式是:\( ...

  7. 【Learning】矩阵树定理 Matrix-Tree

    矩阵树定理 Matrix Tree ​ 矩阵树定理主要用于图的生成树计数. 看到给出图求生成树的这类问题就大概要往这方面想了. 算法会根据图构造出一个特殊的基尔霍夫矩阵\(A\),接着根据矩阵树定理, ...

  8. CF917D. Stranger Trees & TopCoder13369. TreeDistance(变元矩阵树定理+高斯消元)

    题目链接 CF917D:https://codeforces.com/problemset/problem/917/D TopCoder13369:https://community.topcoder ...

  9. BZOJ 1002 轮状病毒 矩阵树定理

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1002 题目大意: 给定n(N<=100),编程计算有多少个不同的n轮状病毒 思路 ...

随机推荐

  1. Oracle安装 - shmmax和shmall设置

    一.概述 在Linux上安装oracle,需要对内核参数进行调整,其中有shmmax和shmall这两个参数,那这两个参数是什么意思,又该如何设置呢? 二.官方文档 在oracle的官方文档( htt ...

  2. Bootstarp框架用法

    Bootstrap框架 Bootstrap框架 2.X 3.X 4.X # 推荐使用3.X版本 使用框架调整页面样式一般都是操作标签的class属性即可 bootstrap需要依赖于jQuery才能正 ...

  3. Python 速通爆肝、列表推导式、生成器、装饰器、生命游戏

    列表推导式.赋值.切片(替换.插入).字符串处理与判断.enumerate().格式化字符串.读写文件.global 关键字.字符串startswith().类与对象.生成器.装饰器.Self.*ar ...

  4. Java语言学习day30--8月5日

    ###10String类的其他方法 * A:String类的其他方法 * a: 方法介绍 * int length(): 返回字符串的长度 * String substring(int beginIn ...

  5. 用 DOM 获取页面的元素方法集合

    document.getElementById('id名')            // 获取页面设置指定 id 的元素 document.getElementsByTagName('标签名')    ...

  6. JavaScript 数学 (Math) 方法

    一.Math 方法 1.Math.round(x) 的返回值是 x 四舍五入为最接近的整数: Math.round(7.8); // 返回 8 Math.round(3.3); // 返回 3 2.M ...

  7. 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 ... 基于. ...

  8. C#语法糖系列 —— 第二篇:聊聊 ref,in 修饰符底层玩法

    自从 C# 7.3 放开 ref 之后,这玩法就太花哨了,也让 C# 这门语言变得越来越多范式,越来越重,这篇我们就来聊聊 ref,本质上来说 ref 的放开就是把 C/C++ 指针的那一套又拿回来了 ...

  9. python学习-Day30

    目录 今日内容详细 作业讲解 设计模式 单例模式 实现思想 编写 pickle模块 今日内容详细 作业讲解 编写元类规定对象的所有数据值转大写 eg: obj.name = 'jason' print ...

  10. Docker极简入门:使用Docker-Compose 搭建redis集群

    为了构建一个集群,我们首先要让 redis 启用集群模式 一个简单的配置文件如下redis.conf # redis.conf file port 6379 cluster-enabled yes c ...