P4208 JSOI2008 最小生成樹計數

2022-03-13 05:07:25 字數 1894 閱讀 2295

???這題竟然不是生成樹計數?直接暴力就行。我們需要知道乙個性質,就是最小生成樹無論長成啥樣,邊權數量是一定的。然後用乘法原理一算就行啦。

好像還有生成樹計數的作法,太麻煩了,就不寫了。

題幹:

題目描述

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

輸入輸出格式

輸入格式:

第一行包含兩個數,n和m,其中1

<=n<=100; 1

<=m<=1000; 表示該無向圖的節點數和邊數。每個節點用1~n的整數編號。

接下來的m行,每行包含兩個整數:a, b, c,表示節點a, b之間的邊的權值為c,其中1

<=c<=1,000,000,000

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

輸出格式:

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

**:

#include#include

#include

#include

#include

#include

#include

using

namespace

std;

#define duke(i,a,n) for(register int i = a;i <= n;++i)

#define lv(i,a,n) for(register int i = a;i >= n;--i)

#define clean(a) memset(a,0,sizeof(a))

const

int inf = 1

<< 30

;typedef

long

long

ll;typedef

double

db;template

void read(t &x)

template

void

write(t x)

const

int n = 2010

;const

int mod = 31011

;struct

node

e[n];

intf[n];

struct

rdqa[n];

int m,n,cnt = 0,ans,sum = 0

;bool

cmp(node a,node b)

int find(int

x)void dfs(int x,int now,int

k)

return

; }

int xx = find(e[now].l),yy =find(e[now].r);

if(xx !=yy)

dfs(x,now + 1

,k);

}int

main()

sort(e + 1,e + m + 1

,cmp);

int tot = 0

;

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

}if(tot != n - 1

)

a[cnt].right =m;

ans = 1

; duke(i,

1,n)

f[i] =i;

duke(i,

1,cnt)}}

printf(

"%d\n

",ans);

return0;

}

P4208 JSOI2008 最小生成樹計數

現在給出了乙個簡單無向加權圖。你不滿足於求出這個圖的最小生成樹,而希望知道這個圖中有多少個不同的最小生成樹。如果兩顆最小生成樹中至少有一條邊不同,則這兩個最小生成樹就是不同的 輸出方案數對31011的模 摘自大佬部落格 find並查集 inline int pls int a,int b 模數不為質...

P4208 JSOI2008 最小生成樹計數

思路 剛看到的時候,因為 n leq 100 所以想到了爆搜,但是這樣做顯然會 tle 所以我們手摸幾組資料找找結論 然後能發現乙個結論 一張圖上的不同最小生成樹中,權值相等的邊的個數是不變的 小證明 用kruskal求最小生成樹時,每一步都是最優的,如果有不同的最小生成樹,則當前步的權值必然小於等...

P4208 JSOI2008 最小生成樹計數

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