JSOI2008 最小生成樹計數

2021-08-21 04:17:36 字數 2782 閱讀 8896

time limit: 1 sec

memory limit: 162 mb

現在給出了乙個簡單無向加權圖。你不滿足於求出這個圖的最小生成樹,而希望知道這個圖中有多少個不同的

最小生成樹。(如果兩顆最小生成樹中至少有一條邊不同,則這兩個最小生成樹就是不同的)。由於不同的最小生

成樹可能很多,所以你只需要輸出方案數對31011的模就可以了。

第一行包含兩個數,

n n

和m' role="presentation" style="position: relative;">m

m,其中

1<=

n<=

100 1

<=

n<=

100;

1<=

m<=

1000

1

<=

m<=

1000

; 表示該無向圖的節點數和邊數。每個節點用1~

n n

的整數編號。接下來的

m' role="presentation" style="position: relative;">m

m行,每行包含兩個整數:

a a

,b' role="presentation" style="position: relative;">bb,

c c

,表示節點

a' role="presentation" style="position: relative;">aa,

b b

之間的邊的權值為

c' role="presentation" style="position: relative;">c

c,其中1≤

c≤1,

000,

000,

000 1≤c

≤1

,000

,000

,000

。資料保證不會出現自回邊和重邊。注意:具有相同權值的邊不會超過10條。

輸出不同的最小生成樹有多少個。你只需要輸出數量對31011的模就可以了。

sample input

4 6

1 2 1

1 3 1

1 4 1

2 3 2

2 4 1

3 4 1

sample output
8

' role="presentation" style="position: relative;">

' role="presentation" style="position: relative;">

' role="presentation" style="position: relative;">

' role="presentation" style="position: relative;">

' role="presentation" style="position: relative;">

其實這道題很結論,雖然網上說要用矩陣樹定理,但是仔細觀察題目的資料範圍,暴力的複雜度是保證可以過的。但是如果題目不保證相等的邊數不超過10的話,就只能使用矩陣樹定理了。

我們先看一眼題。相同的最小生成樹?感覺不是很好下手,因為連刪邊暴力都打不出來。

那我們猜一下結論吧。

1.最小生成樹的邊數都是(n

−1)' role="presentation" style="position: relative;">(n−

1)(n

−1)呃。。。這似乎是句廢話。

2.最小生成樹的每種邊權數量都不變。

這個可以考慮kruskal的過程。如果某種邊權可以加進最小生成樹

x x

條,那麼在生成樹中,它一定會被加入

x' role="presentation" style="position: relative;">x

x條,因為從小到大排序嘛,我能加進去的就加進去。所以不管是哪

x x

條,最後我都會有

x' role="presentation" style="position: relative;">x

x條。

3.每種邊權加進生成樹後縮塊的結果相同。

這個很好理解。如果有兩種不同結果,我們可以把兩個邊同時加入的,這樣的話就和kruskal演算法矛盾了。

綜上所述,我們只需要求每種權值的邊加入生成樹的方案,然後乘法原理算一下就好了。

複雜度是o(

nlog

n∗10!

) o(n

logn

∗10!)

的,然而遠遠卡不滿(可能是資料太水了)。

code(1a了真開心):

#include

#include

#include

#include

using

namespace

std;

struct lxy

void dfs(int u,int tem)

int x=findit(b[u].x),y=findit(b[u].y);

if(x!=y)

dfs(u+1,tem);

}int main()

if(t==n-1) break;

}if(t1)

cnt=0;for(int i=1;i<=n;i++) fa[i]=i;

for(int i=1;i<=m;i++)}}

printf("%d",ans);

}

JSOI2008 最小生成樹計數

bzoj luogu 根據最小生成樹的一些性質,不同的最小生成樹固定權值的邊數是一樣的 而且我們發現這題同權的邊數 10 於是可以預處理出每種權值需要多少條邊,然後爆搜 然後不能路徑壓縮,不然你怎麼回溯.注意到n只有100,暴力並查集搜根沒有任何問題 複雜度 o 邊權數 2 最壞也就是 100 10...

JSOI2008 最小生成樹計數

jsoi2008 最小生成樹計數 題目描述 現在給出了乙個簡單無向加權圖。你不滿足於求出這個圖的最小生成樹,而希望知道這個圖中有多少個不同的最小生成樹。如果兩顆最小生成樹中至少有一條邊不同,則這兩個最小生成樹就是不同的 由於不同的最小生成樹可能很多,所以你只需要輸出方案數對31011的模就可以了。輸...

JSOI 2008 最小生成樹計數 題解

題目傳送門 題目大意 求一張圖有多少棵最小生成樹。最小生成樹有個性質,就是每種長度的邊的數量是固定的。所以先隨便找一棵最小生成樹,考慮長度為 i ii 的邊,先將長度不為 i ii 的最小生成樹中的邊加入進去,然後就形成了若干個連通塊,然後剩下的問題就是用長度為 i ii 的邊將這些連通塊連成一棵樹...