首页 > 其他分享 >Tutte 矩阵

Tutte 矩阵

时间:2023-08-07 12:35:43浏览次数:47  
标签:int det Tutte 矩阵 MAXN widetilde 去掉

基本上是对着这篇博客写的。

定义一张图的一张图 \(G\) 的 Tutte 矩阵 \(\widetilde{A}(G)\) 为:

\[\widetilde{A}(G)_{i,j}=\begin{cases}0&((i,j)\notin E)\\x_{i,j}&((i,j)\in E \land i<j)\\-x_{i,j}&((i,j)\in E\land i>j)\end{cases} \]

即如果 \(i,j\) 没边相连,那么 \(i\) 行 \(j\) 列和 \(j\) 行 \(i\) 列都是 \(0\),否则 \(i\) 行 \(j\) 列上的值和 \(j\) 行 \(i\) 列上的值各自代表一个占位符,且两个占位符互为相反数。

定理 1:一张图有完美匹配当且仅当 \(\det \widetilde{A}(G)\ne 0\)。

考虑行列式的组合意义,相当于我钦定每条边有一个出边,连出若干个环,然后系数取决于逆序对与连边的 \(i>j\) 的次数之和的奇偶性。借鉴 LGV 引理的证明,我们利用行列式异号相消的性质,考虑如果存在一个长度为奇数的环,那么我们将这个环上所有边都反向,那么我们发现这样的操作对 \(p\) 的影响相当于是交换 \(\text{环长}-1\) 次 \(p\) 中的两个元素,而由于交换两个元素,逆序对奇偶性改变,且环长为奇数,所以逆序对个数不变,而环上每个 \(x_{i,j}\) 的符号改变,所以新的排列贡献是原排列贡献的相反数。也就是说如果存在奇环的排列的贡献之和为 \(0\)。这样如果行列式不是 \(0\),说明必然存在一种用偶环分割这张图的方案。这时候我们在偶环上两两匹配即可。

维护多项式很困难,因此考虑将每个 \(x_{i,j}\) 随机赋权,然后计算行列式模一个大质数是否为 \(0\) 即可。


接下来考虑怎么求完美匹配的方案。很直观的想法是枚举每条边,然后尝试将其去掉,判断是否还存在完美匹配。这样复杂度 \(O(n^6)\),显然不能要了。

考虑优化,容易发现 \(\widetilde{A}(G)\) 是斜对角矩阵,即 \(\forall i,j,\widetilde{A}(G)_{i,j}=-\widetilde{A}(G)_{j,i}\),考虑发掘一些性质:

  • 对于 \(n\) 是奇数,大小为 \(n\times n\) 的斜对角矩阵 \(A\),\(\det A=0\)。因为 \(\det A=\det A^T=(-1)^n\det A\),因此 \(\det A=0\)。

  • 对于集合 \(I=\{i_1,i_2,\cdots,i_k\}\),若 \(A\) 中第 \(i_1,i_2,\cdots,i_k\) 行线性无关,则由 \(A\) 的 \(I\) 中的行与 \(I\) 中的列组成的矩阵满秩。

    这个定理同时证明了,一张图的最大匹配数为 \(\dfrac{1}{2}\text{rank}(\widetilde{A}(G))\)。

  • \(\text{rank}(A)\) 为偶数。由性质一可知。

先在考虑证明一些更强的性质:

定理 2:去掉 \(i,j\) 两个点以后,矩阵仍然存在完美匹配,当且仅当去掉 \(\widetilde{A}(G)\) 第 \(i\) 行第 \(j\) 列后,矩阵满秩。

显然前一个命题等价于去掉 \(i,j\) 两行和 \(i,j\) 两列后,矩阵的秩为 \(n-2\)。

充分性:因为去掉第 \(i\) 行 \(j\) 列后,矩阵秩为 \(n-1\),所以去掉 \(i,j\) 两行和 \(i,j\) 两列后,矩阵秩不小于 \(n-3\),而由于斜对角矩阵的秩为偶数,所以去掉 \(i,j\) 两行和 \(i,j\) 两列后,矩阵的秩为 \(n-2\)。

必要性:由于斜对角矩阵的秩为偶数,因此去掉第 \(i\) 行第 \(i\) 列以后,矩阵的秩应为 \(n-2\)。而去掉第 \(i\) 行第 \(i,j\) 两列后,矩阵的秩也为 \(n-2\) 可知,去掉第 \(i\) 行后第 \(j\) 列是其他列的线性组合。所以因为去掉第 \(i\) 行 \(j\) 列后,矩阵秩为 \(n-1\)。

定理 3:去掉 \(i,j\) 两个点以后,矩阵仍然存在完美匹配,当且仅当 \(\widetilde{A}(G)^{-1}_{i,j}\ne 0\)

矩阵的逆等于伴随矩阵除以矩阵的行列式,且 \(\det \widetilde{A}(G)\ne 0\),因此容易由定理 2 推得定理 3。

这样我们可以求 \(n\) 次逆,复杂度 \(O(n^4)\)。继续优化。考虑去掉一行一列后怎么快速维护矩阵的逆的变化,这里引用下博客里的图。

这样去掉一行一列后,我们其实可以 \(O(n^2)\) 地算出去掉这一行一列后,对矩阵的逆的影响。这样总复杂度就可以做到 \(O(n^3)\)。


以上是存在完美匹配的情况,如果不存在完美匹配那情况其实也是类似的,你找出矩阵中最大的线性无关向量就可以规约到存在完美匹配的情况了。

代码实现起来不算太难。一个注意点是你去掉两个点的时候要 check 这两点间是否有边,因为 \(\widetilde{A}(G)^{-1}_{i,j}\ne 0\) 并没有保证 \(i,j\) 之间一定有边。

const int MAXN=1000;
const int MOD=1e9+7;
int qpow(int x,int e){int ret=1;for(;e;e>>=1,x=1ll*x*x%MOD)if(e&1)ret=1ll*ret*x%MOD;return ret;}
mt19937 rng(time(0));
int n,m,k,a[MAXN+5][MAXN+5],b[MAXN+5][MAXN+5];
int tmp[MAXN+5][MAXN+5],c[MAXN+5][MAXN*2+5],d[MAXN+5][MAXN+5];
int res[MAXN+5],id[MAXN+5];
bool ins(int x){
	for(int i=1;i<=n;i++)if(a[x][i]){
		if(!b[i][i]){
			for(int j=i;j<=n;j++)b[i][j]=a[x][j];
			return 1;
		}else{
			int coef=MOD-1ll*qpow(b[i][i],MOD-2)*a[x][i]%MOD;
			for(int j=i;j<=n;j++)a[x][j]=(a[x][j]+1ll*coef*b[i][j])%MOD;
		}
	}return 0;
}
bool vis[MAXN+5];
void del(int x,int y){
	int iv=qpow(d[x][y],MOD-2);
	for(int i=1;i<=k;i++)if(!vis[i])for(int j=1;j<=k;j++)if(!vis[j])
		d[i][j]=(d[i][j]+1ll*(MOD-iv)*d[x][j]%MOD*d[i][y])%MOD;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1,u,v;i<=m;i++){
		scanf("%d%d",&u,&v);int w=rng()%(MOD-1)+1;
		a[v][u]=w;a[u][v]=MOD-w;
	}
	for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)tmp[i][j]=a[i][j];
	vector<int>vec;
	for(int i=1;i<=n;i++)if(ins(i))vec.pb(i);
	printf("%d\n",vec.size()/2);
	for(int i=0;i<vec.size();i++)id[vec[i]]=i+1;
	k=vec.size();
	for(int i=0;i<vec.size();i++)for(int j=0;j<vec.size();j++)
		c[i+1][j+1]=tmp[vec[i]][vec[j]];
	for(int i=1;i<=k;i++)c[i][i+k]=1;
	for(int i=1;i<=k;i++){
		int p=0;
		for(int j=i;j<=k;j++)if(c[j][i])p=j;
		for(int j=i;j<=k*2;j++)swap(c[i][j],c[p][j]);
		int iv=qpow(c[i][i],MOD-2)%MOD;
		for(int j=i;j<=k*2;j++)c[i][j]=1ll*c[i][j]*iv%MOD;
		for(int j=i+1;j<=k;j++){
			for(int t=i+1;t<=k*2;t++)c[j][t]=(c[j][t]+1ll*(MOD-c[j][i])*c[i][t])%MOD;
			c[j][i]=0;
		}
	}
	for(int i=k;i;i--){
		for(int j=i+1;j<=k;j++)for(int t=k+1;t<=k*2;t++)
			c[i][t]=(c[i][t]+1ll*(MOD-c[j][t])*c[i][j])%MOD;
	}
	for(int i=1;i<=k;i++)for(int j=1;j<=k;j++)d[i][j]=c[i][j+k];
	for(int i=1;i<=k;i++){
		if(vis[i])continue;
		int u=i,v=0;
		for(int j=i+1;j<=k;j++)
			if(!vis[j]&&d[i][j]&&tmp[vec[i-1]][vec[j-1]]){
				v=j;break;
			}
		res[vec[u-1]]=vec[v-1];res[vec[v-1]]=vec[u-1];
		vis[u]=vis[v]=1;del(u,v);del(v,u);
	}
	for(int i=1;i<=n;i++)printf("%d%c",res[i]," \n"[i==n]);
	return 0;
}

标签:int,det,Tutte,矩阵,MAXN,widetilde,去掉
From: https://www.cnblogs.com/tzcwk/p/tutte.html

相关文章

  • 矩阵乘法
    前言目前感觉主要就是矩阵加速,一般·看到大一点的范围(加小一点的范围)可能会用到,是一个神奇的东西。运用在广义矩阵和状态转移上面。板子还是打得比较舒服的。广义矩阵乘法具有结合律的条件是分别满足交换律和结合律,内层对外层满足分配律。[NOIOnline#1入门组]魔法题目描......
  • 矩阵乘法 笔记
    众所周知,数是可以进行加减乘除的,那矩阵为啥不可以呢?假设现在我们有两个矩阵\(A\)和\(B\),矩阵大小分别为\(n\timesm\)和\(x\timesy\),矩阵元素对\(mod\)取模。基本运算矩阵加法令\(A+B=C\)。要求:\(n=x\)并且\(m=y\)。其实很简单,就是一一对应着加就行,即......
  • Co-occurrence Network:相关系数矩阵的阈值
    "abs(occor.r)<0.7"这部分代码是对相关系数矩阵进行阈值处理的一部分。这里的"0.7"是一个阈值,用来筛选相关性较强的微生物对。具体来说,对于相关系数矩阵中的每个元素,如果其绝对值小于0.7,则将其设置为0。相关系数范围在-1到1之间,绝对值越接近1表示相关性越强,绝对值越接近0表......
  • 线性方程组数学原理、矩阵原理及矩阵变换本质、机器学习模型参数求解相关原理讨论
    线性方程组数学原理、矩阵原理及矩阵变换本质、机器学习模型参数求解相关原理讨论1.线性方程组0x1:无处不在的线性方程组日常生活或生产实际中经常需要求一些量,用未知数x1,x2,....,xn表示这些量,根据问题的实际情况列出方程组,而最常见的就是线性方程组(当然并不......
  • 矩阵求导与矩阵微分
    简介下面的系列文章来自知乎用户iterator,是我见过最好的矩阵求导教程,没有之一!强烈推荐去看作者原文!矩阵求导的本质与分子布局、分母布局的本质(矩阵求导——本质篇)-知乎矩阵求导公式的数学推导(矩阵求导——基础篇)-知乎矩阵求导公式的数学推导(矩阵求导——进阶篇)-知......
  • LeetCode 热题 100 之 54. 螺旋矩阵
    题目给你一个m行n列的矩阵matrix,请按照顺时针螺旋顺序,返回矩阵中的所有元素。示例1:输入:matrix=[[1,2,3],[4,5,6],[7,8,9]]输出:[1,2,3,6,9,8,7,4,5]示例2:输入:matrix=[[1,2,3,4],[5,6,7,8],[9,10,11,12]]输出:[1,2,3,4,8,12,11,10,9,5,6,7]提示:m==matrix.......
  • doubly block toeplitz matrix 在加速矩阵差卷积上的应用
    文档链接CNN的卷积是执行了\(w'_{i,j}=\sum\limits_{x,y}w_{i+x,j+y}\timesC_{x,y}\),有人认为每次平移卷积核,运算量很大,又是乘法又是加法。现在我们吧\(w_{x,y}\)展开形成一个\([n\timesm,1]\)的向量\(V\),然后构造一个大小为\([(n+1)\times(m+1),n\timesm]\)矩阵......
  • 矩阵计算(导数)
    1标量的导数2亚导数比如说\(y=|x|\)这个函数在x=0的时候时不可导的。当x>0,其到导数为1,x<0,其导数为-1,所以在x=0的这个地方的亚导数就是可以是[-1,1]中的一个数梯度这里主要搞得清楚他的形状∂y/∂x当y是标量,x是向量的时候:它的结果是个横着的矩阵求导向量化的优点......
  • 【线性代数】求逆矩阵的方法
    1.用公式,将求逆转化为求伴随矩阵和行列式2.根据性质,可逆矩阵一定可以写成一系列初等矩阵乘积的形式3.根据可逆的定义,找到能使AB=E成立的矩阵B(不过这个方法一般适合用于一些简单的或者形式特殊的矩阵。4.通过分块矩阵求逆的性质,将大矩阵的求逆转换为小矩阵求逆。......
  • 高维矩阵乘法学习总结
    参考:【深度学习中的数学】高维矩阵乘法规则【全面理解多维矩阵运算】多维(三维四维)矩阵向量运算-超强可视化baseKnowlegde:高维矩阵相当于二维矩阵的顺序堆叠相同维度数目举例:Ashape[a,b,c,d],Bshape[e,f,g,h]For高维(除第一维和第二维之外)长度相同:(eg.\(a......