在圖論中,樹的定義是連通且無環的無向圖。對於一棵有 n
n 個節點且節點從 1
1 到 n
n 編號的樹,它的 prufer 序列是乙個唯一的長為 n−2
n−2 的標號序列。 prufer 序列的構造方法:每次刪除樹中標號最小的葉子節點(即度為 1
1 的節點),將該點的鄰居加到當前 prufer 序列的末尾,直到只剩兩個節點為止。
例子:
給定乙個 n
n 個頂點(從 1
1 到 n
n 標號), m
m 條邊的無向圖 gg(g
g 中無重邊或自環)。隨機選擇 g
g 的一棵生成樹,計算他的 prufer 序列的和 s
s,重複元素只算一次。 請計算隨機變數 s
s 的期望。注意,g
g 的生成樹或某棵生成樹的 prufer 序列都可能不存在,這種情況下,我們認為隨機變數 s
s 的值為 00。
為了避免精度問題, 算出實際的期望值乘以圖 g
g 的不同生成樹的數目以後的值即可。 這個值可能很大,請輸出它對 109+
7109+7
取模以後的值。
每個輸入檔案包含多組測試資料。輸入檔案的第一行是測試資料組數 t
t (t≤10
t≤10
)。 對於每組測試資料,第一行是兩個整數 n,m
n,m (3≤n
≤100,0
≤m≤(
n−1)
n23≤n≤100,0≤m≤(n−1)n2
),分別是圖的點數和邊數;接下來 m
m 行,每行包含兩個整數 u,v
u,v(1≤u
,v≤n
1≤u,v≤n,u≠
vu≠v
),表示圖中的一條邊。
輸出 t
t 行,每行是對應的答案。
13 31 2
2 31 3
6題目大意:求所有生成樹的prufer序列和(prufer中有重複序列的只算一次!!!)
題解:這樣的話,對於每一顆生成樹,我們可以把所有的點全都加進去,然後再減去葉子結點的和。
我們不可能找到所有的生成樹然後乙個乙個的計算,因此我們用矩陣樹定理來做。
我們先計算圖所有的點的和,並且乘以生成樹的數量,把他們放在sum裡。然後再把所有的葉子結點減去,就好了
如果乙個葉子節點出現在一顆子樹裡,那麼把這個點去掉,仍然可一得到圖的該生成樹,而如果這個點是內部節點就不行了。
注意:如果這個葉子節點的度不為1,那麼要用這個葉子節點的度數乘以生成樹的數量,才是這個葉子節點對應生成樹的個數。
sum -= 去掉該節點生成樹的數量*該節點的度*該節點的值。
最後得到的sum就是答案
**:
#include。
#include#include using namespace std;
#define zero(x)((x>0? x:-x)<1e-15)
#define int long long
int const maxn = 105;
const int mod = 1e9 + 7;
int a[maxn][maxn];
int b[maxn][maxn];
int g[103][103];
int d[105];
int n, m;
int det(int a[maxn][maxn], int n)
prep(n,-1);
int sum = det(a,n-1)*((1+n)*n/2) % mod;
for(int i = 0;i < n-1;i++)
{ prep(n,i);
sum = (sum - (i+1)*d[i] % mod * det(a,n-1) % mod + mod)%mod;
//cout<
prufer序列複習小結
快要省選了。抽點時間複習一下東西 以免漏了一些東西 為了在省選之前覺得自己什麼都會 每一次選擇乙個編號最小,並且度數為1的點 把它刪掉 然後讓他唯一連向的點加入prufer序列 如果只有兩個點就結束 這個的話,你可以理解為有乙個陣列a 表示每乙個數在prufer裡面出現的次數 然後每一次,你就選出p...
Prufer序列相關
最近做到一些題,用到了prufer序列,挺有用的,在這裡學習一下。prufer數列是無根樹的一種數列,通過乙個prufer序列可以唯一表示一棵頂點帶標號的無根樹,點數為n的樹轉化來的prufer數列長度為n 2,它有很多的性質 一種生成prufer序列的方法是迭代刪點,直到原圖僅剩兩個點。對於一棵頂...
prufer 序列 學習筆記
上周五看了一下,發現不是很難,今天再看了一眼,把板題做了,順便看了另外一道 懶得碼了 其實很簡單,我們定義一顆無根樹的 prufer 序列為,欽定任意乙個點為根 方便確定父子關係 每次從葉子中選出乙個編號最小的點,把它的父親加入到 prufer 序列中,並刪掉該節點。不難看出,我們最後會有 n 2 ...