日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

生成树的计数 Matrix-Tree(矩阵树)定理

發(fā)布時(shí)間:2025/3/15 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 生成树的计数 Matrix-Tree(矩阵树)定理 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

信息學(xué)競(jìng)賽中,有關(guān)生成樹(shù)的最優(yōu)化問(wèn)題如最小生成樹(shù)等是我們經(jīng)常遇到的,而對(duì)生成樹(shù)的計(jì)數(shù)及其相關(guān)問(wèn)題則少有涉及。事實(shí)上,生成樹(shù)的計(jì)數(shù)是十分有意義的,在許多方面都有著廣泛的應(yīng)用。本文從一道信息學(xué)競(jìng)賽中出現(xiàn)的例題談起,首先介紹了一種指數(shù)級(jí)的動(dòng)態(tài)規(guī)劃算法,然后介紹了行列式的基本概念、性質(zhì),并在此基礎(chǔ)上引入Matrix-Tree定理,同時(shí)通過(guò)與一道數(shù)學(xué)問(wèn)題的對(duì)比,揭示了該定理所包含的數(shù)學(xué)思想。最后通過(guò)幾道例題介紹了生成樹(shù)的計(jì)數(shù)在信息學(xué)競(jìng)賽中的應(yīng)用,并進(jìn)行總結(jié)。


生成樹(shù)的計(jì)數(shù) Matrix-Tree定理


問(wèn)題的提出

?

[例一]高速公路(SPOJ 104 Highways)

?

一個(gè)有n座城市的組成國(guó)家,城市1至n編號(hào),其中一些城市之間可以修建高速公路。現(xiàn)在,需要有選擇的修建一些高速公路,從而組成一個(gè)交通網(wǎng)絡(luò)。你的任務(wù)是計(jì)算有多少種方案,使得任意兩座城市之間恰好只有一條路徑?

數(shù)據(jù)規(guī)模:1≤n≤12。

[分析]

?

我們可以將問(wèn)題轉(zhuǎn)化到成圖論模型。因?yàn)槿我鈨牲c(diǎn)之間恰好只有一條路徑,所以我們知道最后得到的是原圖的一顆生成樹(shù)。因此,我們的問(wèn)題就變成了,給定一個(gè)無(wú)向圖G,求它生成樹(shù)的個(gè)數(shù)t(G)。這應(yīng)該怎么做呢?

經(jīng)過(guò)分析,我們可以得到一個(gè)時(shí)間復(fù)雜度為O(3n*n2)的動(dòng)態(tài)規(guī)劃算法,因?yàn)樵}的規(guī)模較小,可以滿足要求。但是,當(dāng)n再大一些就不行了,有沒(méi)有更優(yōu)秀的算法呢?答案是肯定的。在介紹算法之前,首先讓我們來(lái)學(xué)習(xí)一些基本的預(yù)備知識(shí)。


新的方法介紹

?????? 下面我們介紹一種新的方法——Matrix-Tree定理(Kirchhoff矩陣-樹(shù)定理)。Matrix-Tree定理是解決生成樹(shù)計(jì)數(shù)問(wèn)題最有力的武器之一。它首先于1847年被Kirchhoff證明。在介紹定理之前,我們首先明確幾個(gè)概念:

1、G的度數(shù)矩陣D[G]是一個(gè)n*n的矩陣,并且滿足:當(dāng)i≠j時(shí),dij=0;當(dāng)i=j時(shí),dij等于vi的度數(shù)。

2、G的鄰接矩陣A[G]也是一個(gè)n*n的矩陣, 并且滿足:如果vi、vj之間有邊直接相連,則aij=1,否則為0。

我們定義G的Kirchhoff矩陣(也稱為拉普拉斯算子)C[G]為C[G]=D[G]-A[G],則Matrix-Tree定理可以描述為:G的所有不同的生成樹(shù)的個(gè)數(shù)等于其Kirchhoff矩陣C[G]任何一個(gè)n-1階主子式的行列式的絕對(duì)值。所謂n-1階主子式,就是對(duì)于r(1≤r≤n),將C[G]的第r行、第r列同時(shí)去掉后得到的新矩陣,用Cr[G]表示。

生成樹(shù)計(jì)數(shù)

算法步驟:

1、?構(gòu)建拉普拉斯矩陣

? ? ?Matrix[i][j] =

degree(i) , i==j

??????????-1,i-j有邊

???????????0,其他情況

2、?去掉第r行,第r列(r任意)

3、?計(jì)算矩陣的行列式

論文 周冬 《生成樹(shù)計(jì)數(shù)應(yīng)用》

#include <map> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; const int maxn = 105; const int maxm = 100005; const int INF = 1e9; int degree[maxn]; ll g[maxn][maxn]; int n, m; ll det(ll a[][maxn], int n) { ll ret = 1; for(int i=1; i<n; ++i){ for(int j=i+1; j<n; ++j){ while(a[j][i]){ ll t = a[i][i]/a[j][i]; for(int k=i; k<n; ++k){ a[i][k] = (a[i][k]-a[j][k]*t); } for(int k=i; k<n; ++k){ swap(a[i][k], a[j][k]); } ret = -ret; } } if(a[i][i]==0){ return 0; } ret = ret*a[i][i]; } if(ret<0){ ret = -ret; } return ret; } void solve() { int u, v; memset(degree, 0, sizeof degree ); memset(g, 0, sizeof g ); scanf("%d%d", &n, &m); while(m--){ scanf("%d%d", &u, &v); u--,v--; g[u][v] = g[v][u] = -1; degree[u]++; degree[v]++; } for(int i=0; i<n; ++i){ g[i][i] = degree[i]; } printf("%lld\n", det(g, n)); } int main() { int t; scanf("%d", &t); while(t--){ solve(); } return 0; }


轉(zhuǎn)載于:https://www.cnblogs.com/tham/p/6827125.html

總結(jié)

以上是生活随笔為你收集整理的生成树的计数 Matrix-Tree(矩阵树)定理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。