最小生成樹

2022-05-08 04:30:07 字數 1371 閱讀 5053

話說正在 jmy 愁苦如何籌錢給大家買汽水的時候,他遇上了一位魔法師。魔法師希望 jmy能幫他破解魔法書的咒語。如果 jmy 做到了,就幫他付所有買汽水的錢。

魔法書上畫了乙個完全圖(每兩個點之間有且只有一條邊),每個點都有乙個獨一無二的[1,n]內的編號,jmy 的任務是要找到最小生成樹,以此作為魔法樹,從而破解咒語。

對於完全圖的邊(i,j) (i≠j)的邊權恰好就等於 i,j 兩個數字的最大公約數。

特別地,要作為魔法樹,必須滿足樹指定某個點為根後,所有除根以外的節點的父親的標號必須小於自身標號。

jmy 一眼就看出了最小生成樹的邊權和。然而咒語卻是最小生成樹的個數。 為了保證大家都有汽水喝,你能幫幫 jmy 嗎?

一行僅乙個數 n,表示完全圖的大小。

一行乙個整數,表示答案對 100,000,007 取模(mod)的結果。

【資料規模】

對於 10%的資料,n≤5;

對於 30%的資料,n≤8;

對於 40%的資料,n≤10;

對於 70%的資料,n≤5,000;

對於 100%的資料,n≤20,000。

手玩可以發現,要求的就是尤拉函式的第2到n項的積。
簡略證(xia)明(che):
首先最小生成數的權值和肯定是n-1,這個很顯然。
然後要滿足題目說的,每個點的父親只能是比他小的點,而且邊權要唯一,

那麼只能連線和它互質的數,然後就是乘法原理啊。

1 #include

2 #include3 #include4 #include5 #include6 #include7 #include

8 #include9 #include10 #include11 #include12 #include13 #include14

#define maxn 20010

15#define mod 100000007

16using

namespace

std;

17int

bj[maxn],su[maxn],phi[maxn];

18int

main()

1934

else phi[su[j]*i]=phi[i]*(su[j]-1

);35}36

}37long

long ans=1;38

for(int i=2;i<=n;i++)

39 ans=(ans*phi[i])%mod;

40 printf("

%lld

",ans);

41return0;

42 }

最小生成樹 次小生成樹

一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 1.兩點之間的路徑是唯一的。2.邊數等於點數減一。3.連線任意兩點都會生成乙個環。對於乙個無向聯通圖g的子圖,如果它包含g的所有點,則它被稱為g的生成樹,而各邊權和最小的生成樹則被稱...

最小生成樹

package 圖 最小生成樹是用最少的邊吧把所有的節點連線起來。於是和圖的深度優先搜素差不多。class stack public void push int key public int pop 檢視棧頂的元素 public int peek public boolean isempty cla...

最小生成樹

define max vertex num 20 最大頂點數 typedef int adjmatrix max vertex num max vertex num 鄰接矩陣型別 typedef char vertextype typedef struct mgraph struct dnodecl...