P3953 [NOIP2017 提高组] 逛公园 (dp + 最短路)
求有向图中
部分分
我们发现有向图中存在后效性,不好动态规划,但我们仔细思考后,在不存在
考虑优化
假设
所以
70pts:此时我们转移就可以把按
100pts:一样有无后效性,因为对于
但有一个特殊情况就是图中
总结:特殊性质的优化,变为无后效性问题
#include <bits/stdc++.h>
typedef long long ll;
int read() {
int x = 0, f = 1;
char c = getchar();
while(!isdigit(c)) {
if(c == '-') f = -1;
c = getchar();
}
while(isdigit(c)) {
x = (x << 3) + (x << 1) + (c - '0');
c = getchar();
}
return x * f;
}
bool flg;
int t, n, m, k, p, cnt, cnt2, ans;
int h[100010], h2[100010], dis[100010], vis[100010], f[100010][51], ins[100010][51];
struct node {
int to, nxt, w;
} e[200010], e2[200010];
void add(int u, int v, int w) {
e[++cnt].to = v;
e[cnt].nxt = h[u];
e[cnt].w = w;
h[u] = cnt;
}
void add2(int u, int v, int w) {
e2[++cnt2].to = v;
e2[cnt2].nxt = h2[u];
e2[cnt2].w = w;
h2[u] = cnt;
}
struct ac {
int v, w;
friend bool operator < (ac a, ac b) {
return a.w > b.w;
}
} tmp;
void dij(int s) {
std::priority_queue<ac> q;
for(int i = 1; i <= n; i++) dis[i] = 0x3f3f3f3f, vis[i] = 0;
dis[s] = 0;
q.push({s, 0});
while(!q.empty()) {
int u = q.top().v;
q.pop();
if(vis[u]) continue;
vis[u] = 1;
for(int i = h[u]; i; i = e[i].nxt) {
int v = e[i].to;
if(dis[v] > dis[u] + e[i].w) {
dis[v] = dis[u] + e[i].w;
tmp.v = v, tmp.w = dis[v];
q.push(tmp);
}
}
}
}
int dp(int u, int j) {
if(j < 0) return 0;
if(ins[u][j]) {
flg = 1;
return 0;
}
if(f[u][j]) return f[u][j];
ins[u][j] = 1;
int ret = 0;
for(int i = h2[u]; i; i = e2[i].nxt) {
int v = e2[i].to;
ret = (ret + dp(v, dis[u] + j - e2[i].w - dis[v])) % p;
if(flg) return 0;
}
ins[u][j] = 0;
return f[u][j] = ret;
}
void Solve() {
t = read();
while(t--) {
n = read(), m = read(), k = read(), p = read();
for(int i = 1; i <= m; i++) {
int u = read(), v = read(), w = read();
add(u, v, w), add2(v, u, w);
}
dij(1);
ans = 0, flg = 0;
memset(f, 0, sizeof(f));
memset(ins, 0, sizeof(ins));
dp(1, 0);
f[1][0] = 1;
for(int i = 0; i <= k; i++) {
ans = (ans + dp(n, i)) % p;
}
if(flg) std::cout << "-1\n";
else std::cout << ans << "\n";
for(int i = 1; i <= n; i++) {
h[i] = h2[i] = 0;
}
cnt = cnt2 = 0;
}
}
int main() {
Solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具