Educational Codeforces Round 125 (Rated for Div. 2) E. Star MST
折磨了我三天的,终于看懂啦。
首先,如果想要有题目要求的效果,那么最短的边一定都是与相连的,就是一个菊花图,生成树里的边就是最短的边。
表示已经有个点与相连,且最大权值不超过的方案。
那么我们考虑如何从转移到,看下图,已经连接了个点,且最大值不超过。
那么我们从右边个点中选个点号点相连,令它们的边权是,那么也就是说现在有个点的与相连的那条边权已经确定了,这就是我们的的状态。
那么对于现在已经选定的这个点,右边t个点内部只要边权满足就可以随便连,然后个点与个点之间同样只要满足就可以随便连。
(为了图的美观,左边个点与右边个点先不画边了)
粉红色表示边权为的边,绿色表示个点内部连线,边权满足,连接条,左边个点与右边个点相连有条,边权有中选择,所以可以得出状态方程了:
结果:表示往结点添加个点,最大边权为
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int Mod = 998244353;
const int N = 300;
ll f[N][N]; //与1相连的点有i个 且最大边权不超过j的方案数
ll C[N][N];
ll qmi(ll a, ll b) {
ll res = 1;
while (b) {
if (b & 1) res = res * a % Mod;
b >>= 1;
a = a * a % Mod;
}
return res % Mod;
}
int main() {
int n, k;
cin >> n >> k;
for (int i = 0; i < N; i++) {
for (int j = 0; j <= i; j++) {
if (!j) C[i][j] = 1;
else C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % Mod;
}
}
f[0][0] = 1;
for (int i = 0; i <= n - 1; i++) { //已经有i个点合并进来
for (int j = 0; j <= k; j++) { //最大边权不超过j
for (int t = 0; t <= n - i - 1; t++) { //从剩余的点中选t个的边权是i + 1
f[i + t][j + 1] = (f[i + t][j + 1] + f[i][j] * C[n - 1 - i][t] % Mod * qmi(k - j, t * i + t * (t - 1) / 2) % Mod) % Mod;
}
}
}
cout << f[n - 1][k] << "\n";
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端