E. Star MST (DP) (Educational Codeforces Round 125)
阿新 • • 發佈:2022-03-23
E. Star MST
Educational Codeforces Round 125 (Rated for Div. 2) E. Star MST
題目:
輸入n, k。指n個點構成的完全無向圖(完全圖指任意兩點間有一條邊),加權邊取值為1~k之間,如果與1點相連的邊的權值和與MST的權值和相等,則這樣的圖稱為"美麗的"。問這樣的圖的數量。結果模 998244353
。
題解:
學習自cf使用者Heltion的解法。考慮dp[i][j]為i個點,取值在1~k之間的滿足要求圖數量。它的轉移如下:
\[dp[i][j] = \sum_{z = 1}^{i} dp[z][j-1]*C_{i-1}^{z-1}*(k-j+1)^{[(z-1)*(i-z) + (i-z)*(i-z+1)/2]} \]解釋一下:就是現在已經有包括1點在內的z個點數量求出來了,考慮把剩下i - z個點和1連起來。這些點和1點連線的權值是j。\(C_{i-1}^{z-1}\)
如圖:黑色是已經連好的邊,黃色是為了滿足要求的權值為j的邊,綠色是不影響結果的邊。
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<algorithm> #include<queue> #include<cmath> using namespace std; typedef pair<double, int> PII; typedef long long ll; const int N = 1e3 + 5; const ll mod = 998244353; ll qpow(ll a, ll b) { ll res = 1; while(b){ if(b & 1) res = (res * a) % mod; a = (a * a) % mod; b >>= 1;} return res; } ll gcd(ll a, ll b) { return !b ? a : gcd(b, a % b); } ll lcm(ll a, ll b) { return a * b / gcd(a, b); } ll n, k; ll dp[N][N]; ll fac[N], inv[N]; void init(){ fac[0] = inv[0] = 1; for(int i = 1; i < N; ++ i) fac[i] = fac[i - 1] * i % mod; inv[N - 1] = qpow(fac[N - 1], mod - 2); for(int i = N - 2; i >= 0; -- i) inv[i] = inv[i + 1] * (i + 1) % mod; } int main(){ init(); scanf("%lld%lld",&n, &k); dp[1][0] = 1; for(int i = 1; i <= n; ++ i){ for(int j = 1; j <= k; ++ j){ for(int z = 1; z <= i; ++ z){ ll tp = dp[z][j - 1] * fac[i - 1] % mod * inv[z - 1] % mod * inv[i - z] % mod; ll tpp = qpow(k - j + 1, (z - 1) * (i - z) + (i - z) * (i - z - 1) / 2) % mod; dp[i][j] = (dp[i][j] + tp * tpp) % mod; } } } printf("%lld\n",dp[n][k]); return 0; }