1. 程式人生 > 其它 >cf1172 B. Nauuo and Circle(排列組合)

cf1172 B. Nauuo and Circle(排列組合)

題意:

已知一棵有n個頂點的樹。你要把樹的所有頂點放在一個環上,要求頂點不能重疊且所有邊不相交(當然在端點處可以相交)。然後任選一個點作為起點開始順時針點數,可以得到一個n的排列。問不同的排列有多少種。

思路:

\(root\) 為根節點,\(u_i\)\(root\) 的兒子們。\(tr(x)\) 表示以 \(x\) 為根的樹。

對每個 \(u_i\)\(tr(u_i)\) 的所有點在環上一定是在一起的。

先不選起點。先放置 \(root,tr(u_1), tr(u_2),\cdots,tr(u_{deg[root]})\) 。注意 \(n\) 個點的環排列數為 \(n!/n=(n-1)!\)

,所以方案數為 \((deg[root]+1-1)!=(deg[root])!\)

然後看某個 \(tr(u_i)\) 怎樣放置。設 \(u_i\) 的兒子為 \(v_j\) ,放置 \(u_i,tr(v_1),tr(v_2),\cdots ,tr(v_{deg[u_i]-1})\) ,共 \(deg[u_i]\) 個點。注意這時不用環排列數,應該是正常排列數 \((deg[u_i])!\)

上面的結果相乘,就是 \(\sum\limits_{i=1}^{n}(deg[i])!\) 。最後任選一點為起點,乘個 \(n\)

ll ans = n;
for(int i = 1; i <= n; i++) (ans *= jie[deg[i]]) %= mod;
cout << ans;