1. 程式人生 > >生成生成樹計數 --- Matrix-Tree定理(基爾霍夫矩陣樹定理)

生成生成樹計數 --- Matrix-Tree定理(基爾霍夫矩陣樹定理)

模板題點這
題目大意:
*一個有n座城市的組成國家,城市1至n編號,其中一些城市之間可以修建高速公路;
*需要有選擇的修建一些高速公路,從而組成一個交通網路;
*計算有多少種方案,使得任意兩座城市之間恰好只有一條路徑;
模板 :

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
const int
maxn=20; int degree[maxn]; //度數矩陣,記錄每一個點的度數. //不懂就看下上面那個定理證明. ll a[maxn][maxn]; //矩陣樹, 對角線是度數矩陣的每一個數,其餘地方為 a[i][j] = a[i][j] - vis[i][j] ; int vis[maxn][maxn]; //臨接矩陣,u與v相連就是等於1,否則就是為0.注意是無向邊. ll det(int n) //生成樹計數:Matrix-Tree定理 //這個是求行列式的精華啊(實質上這個子函式就是用來 //求行列式的值的!)(所以也適用於求行列式值的題) { ll ret=1
; for(int i=2; i<=n; i++) //計算任意一個n-1階行列式的值就是答案. { 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*=a[i][i]; //加一下 } if(ret<0) // 可以縮合為 ((ret % p ) + p ) % p ; ret=-ret; return ret; } //這個就是程式的主要函式,計算行列式的值. int main() { int tcase; scanf("%d",&tcase); while(tcase--) { memset(degree,0,sizeof(degree)); memset(a,0,sizeof(a)); memset(vis,0,sizeof(vis)); int n,m; scanf("%d%d",&n,&m); int u,v; while(m--) { scanf("%d%d",&u,&v); vis[u][v]=1; //相連就是1,否則就是0. vis[v][u]=1; degree[u]++; degree[v]++; } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(i==j) a[i][j] = degree[i]; else a[i][j] -= vis[i][j]; } } printf("%lld\n",det(n)); } return 0; }

綜合一下,還可以這樣寫:
(這個是在定理上面加強版,把一些步驟直接在縮合在了一起)
靈活點就是在目標矩陣中,為:(對於一些變形題就這樣處理).
無向圖的基爾霍夫矩陣: 對角線上表示每個點的度數,若ij之間有邊則矩陣ij處為-1
無向圖的生成樹的數目為: 任意一個n-1階主子式的行列式的絕對值.

 while(m--)
        {
            scanf("%d%d",&u,&v);
            a[u][v]=a[v][u]=-1;     //u與v相連,所以在目標矩陣中為-1.
            degree[u]++;
            degree[v]++;
        }
 for(int i=1;i<=n;i++)
      a[i][i]=degree[i];

相關推薦

生成成樹計數 --- Matrix-Tree定理(矩陣定理)

模板題點這 題目大意: *一個有n座城市的組成國家,城市1至n編號,其中一些城市之間可以修建高速公路; *需要有選擇的修建一些高速公路,從而組成一個交通網路; *計算有多少種方案

成樹計數-Matrix-Tree定理

/* *演算法引入: *給定一個無向圖G,求它生成樹的個數t(G); * *演算法思想: *(1)G的度數矩陣D[G]是一個n*n的矩陣,並且滿足:當i≠j時,dij=0;當i=j時,dij等於vi的度數; *(2)G的鄰接矩陣A[G]是一個n*n的矩陣,並且滿

UVA10766(Organising the Organisation)成樹計數-Matrix-Tree定理

/* *題目地址: *http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1707; * *題目大意:

hdu4305Lightning 成樹計數矩陣)+高斯消元+逆元

題意:比較裸的生成樹計數問題。   如何處理生成樹計數問題? 基爾霍夫矩陣: if i==j  Kir[i][j] = i的度數 if i!=j   Kir[i][j] = i到j的平行邊的個數的負數 即,基爾霍夫矩陣 = 度數矩陣 - 鄰接矩陣 將基爾霍夫矩陣刪去第i

【hdu5304】成樹計數矩陣 DP

給一個無向圖,求有多少個子圖是基環樹。 列舉環後縮點,再求生成樹計數。 2^n列舉環上的點,dp預處理出每個集合的環的個數(預設以編號最小的點為起點),用f[i][s]表示環尾為i,點集為s。 #include <iostream> #include <c

成樹個數(矩陣

Problem 2. tcount Input file: tcount.in Output file: tcount.out Time limit: 1 second Mr.H發現了一個無向連

BZOJ 1002 - 輪狀病毒 - [矩陣(待補)+高精度][FJOI2007]

() out strlen esp lean 例如 計算 stream height 題目鏈接:https://www.lydsy.com/JudgeOnline/problem.php?id=1002 Description  輪狀病毒有很多變種,所有輪狀病毒的變種都是從

BZOJ.1016.[JSOI2008]最小生成樹計數(Matrix Tree定理 Kruskal)

main mat 計算 def tdi str 題目 matrix include 題目鏈接 最小生成樹有兩個性質: 1.在不同的MST中某種權值的邊出現的次數是一定的。 2.在不同的MST中,連接完某種權值的邊後,形成的連通塊的狀態是一樣的。 \(Solution1\)

電路 - 定律(KLL);節點流入電流等於流出電流。

定律 公式 通過 假設 mage 14. 一個 表示 nbsp 下面是我在學習STM32 中ADC測量電壓,時候接觸掉ADC的測量範圍在0~3.3V 之間,不滿足於實際使用,用於電路知識設計電壓放大電路。(圖片來自野火) 上面個的電路,可以等效出一個電路公式:(

成樹計數Matrix-Tree定理

以下轉載自http://blog.csdn.net/jarily/article/details/8901363 /* *演算法引入: *給定一個無向圖G,求它生成樹的個數t(G); * *演算法思想: *(1)G的度數矩陣D[G]是一個n*n的矩陣,並且滿足:

成樹計數及應用 Matrix-Tree

log blog 生成樹計數 mathjax 插值 tps 生成樹 www. 應用 例:給定一個圖,圖上每條邊是紅色或藍色,求恰有 k 條紅邊的生成樹個數. n≤50. Matrix-Tree定理,對於限制條件可以利用多項式,把紅邊邊權設為 X,藍邊為1. 最後求行列式得到

成樹計數的MatrixTree定理

在省選級別的題目裡面,我們會發現有一類生成樹計數的題目。就是給定一個圖G={V,E},問這個圖生成樹有多少棵(節點和邊都不同)。 這裡我們可以用基爾霍夫矩陣做。我們定義一個圖有度數矩陣A,有鄰接矩陣B

HDU 4305 Lightning (成樹計數+矩陣定理+逆元)

題意:給你n個點,如果兩個點的距離小於等於r那麼就連一條邊,讓你求生成樹的個數。 題解: 對於無向圖G,它的Kirchhoff矩陣C定義為它的度數矩陣D減去它的鄰接矩陣A。顯然,這樣的定義滿足剛才描述的性質。 有了Kirchhoff矩陣這個工具,我們可以引入Matri

uva10766成樹計數

als mes art 算子 技術分享 math 個數 main mat 此類題是給定一個無向圖,求所有生成樹的個數,生成樹計數要用到Matrix-Tree定理(Kirchhoff矩陣-樹定理) G的度數矩陣D[G]是一個n*n的矩陣,並且滿足:當i≠j時,dij=0;當i

hdu4305成樹計數

open assert with for def com false tor == 先預處理出距離,然後判斷是否可行,要註意判斷是否在一條直線上時判斷是在兩側還是一邊(wa了四次) double型數據 #include<map> #include<se

【BZOJ2467】[中山市選2010]成樹 矩陣定理

n) 生成樹 scan ans 中山市選 work font 以及 pri 【BZOJ2467】[中山市選2010]生成樹 Description 有一種圖形叫做五角形圈。一個五角形圈的中心有1個由n個頂點和n條邊組成的圈。在中心的這個n邊圈的每一條邊同時也是某一個

矩陣定理(Matrix Tree)學習筆記

cstring 相關 () str eof bsp lld open csdn 如果不談證明,稍微有點線代基礎的人都可以在兩分鐘內學完所有相關內容。。 行列式隨便找本線代書看一下基本性質就好了。 學習資源: https://www.cnblogs.com/candy99/p

【LOJ】#2320. 「清華集訓 2017」成樹計數

rac res 然而 除了 加法 wap OS 代碼 reg 題解 我,理解題解,用了一天 我,卡常數,又用了一天 到了最後,我才發現,我有個加法取模,寫的是while(c >= MOD) c -= MOD 我把while改成if,時間,少了 六倍。 六倍。 六倍!!

[BZOJ1494]成樹計數

cto operator 個數 最後一行 判斷 state for break desc [BZOJ1494] [NOI2007]生成樹計數 Description 最近,小棟在無向連通圖的生成樹個數計算方面有了驚人的進展,他發現:·n個結點的環的生成樹個數為n。·n個結點

bzoj1494 成樹計數 (dp+矩陣快速冪)

sets 增加 set 基本 表示 2種 least 欺詐 main 題面欺詐系列... 因為一個點最多只能連到前k個點,所以只有當前的連續k個點的連通情況是對接下來的求解有用的 那麽就可以計算k個點的所有連通情況,dfs以下發現k=5的時候有52種。 我們把它們用類似於並