1. 程式人生 > >計蒜客 18018 熱愛工作的蒜蒜 最短路+dp

計蒜客 18018 熱愛工作的蒜蒜 最短路+dp

tar int 距離 code div top with per spa

鏈接:

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