计蒜客 18018 热爱工作的蒜蒜 最短路+dp
Posted Flowersea
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计蒜客 18018 热爱工作的蒜蒜 最短路+dp相关的知识,希望对你有一定的参考价值。
链接:
https://nanti.jisuanke.com/t/18018
题意:
蒜蒜要从1-n,中间有地下的路和地上的路,地下的路长度都为1,且不会被淋,地上的路长度有权值,
问从1-n在距离不超过l的情况下,使得淋雨的路程最少
题解:
定义dp[i][j],表示在走了j条地下的路的情况下从1到i的最短路,然后就是最短路了
只不过push的时候还要记下j的值
代码:
31 struct Node { 32 int to, cost, id; 33 bool operator<(const Node &t)const { 34 return cost > t.cost; 35 } 36 }; 37 struct edge { int to, cost; }; 38 vector<int> iG[MAXN]; 39 vector<edge> eG[MAXN]; 40 int dp[MAXN][MAXN]; 41 int n, m1, m2, l; 42 43 void dijkstra() { 44 priority_queue<Node>que; 45 memset(dp, 0x3f, sizeof(dp)); 46 dp[1][0] = 0; 47 que.push(Node{ 1,0,0 }); 48 while (!que.empty()) { 49 Node p = que.top(); que.pop(); 50 int v = p.to; 51 if (dp[v][p.id] < p.cost) continue; 52 rep(i, 0, eG[v].size()) { 53 edge e = eG[v][i]; 54 if (dp[e.to][p.id] > p.cost + e.cost) { 55 dp[e.to][p.id] = p.cost + e.cost; 56 que.push(Node{ e.to,dp[e.to][p.id],p.id }); 57 } 58 } 59 if (p.id == m1) continue; 60 rep(i, 0, iG[v].size()) { 61 int to = iG[v][i]; 62 if (dp[to][p.id + 1] > p.cost + 1) { 63 dp[to][p.id + 1] = p.cost + 1; 64 que.push(Node{ to,dp[to][p.id + 1],p.id + 1 }); 65 } 66 } 67 } 68 } 69 70 int main() { 71 ios::sync_with_stdio(false), cin.tie(0); 72 int T; 73 cin >> T; 74 while (T--) { 75 rep(i, 0, MAXN) iG[i].clear(), eG[i].clear(); 76 cin >> n >> m1 >> m2 >> l; 77 rep(i, 0, m1) { 78 int a, b; 79 cin >> a >> b; 80 iG[a].pb(b); 81 iG[b].pb(a); 82 } 83 rep(i, 0, m2) { 84 int u, v, c; 85 cin >> u >> v >> c; 86 eG[u].pb(edge{ v,c }); 87 eG[v].pb(edge{ u,c }); 88 } 89 dijkstra(); 90 int ans = INF; 91 rep(i, 0, m1 + 1) if (dp[n][i] <= l) ans = min(ans, dp[n][i] - i); 92 if (ans == INF) ans = -1; 93 cout << ans << endl; 94 } 95 return 0; 96 }
以上是关于计蒜客 18018 热爱工作的蒜蒜 最短路+dp的主要内容,如果未能解决你的问题,请参考以下文章
[计蒜客] ACM-ICPC 2018 南京赛区网络预赛 | 部分题解 | 线段树 + 线性筛 + 最短路