【1018 30 Dijkstra dfs】 Public Bike Management
传送门
题意
给给定 \(C_{max},N,S_p,M\) ,\(N,M\)表示节点个数和边数,\(S_p\) 表示 目标点,\(\frac{cmax}{2}\)表示目标点权值。如果小于就从 \(0\) 进行 send,大于就 back,求从 \(0\) 到 \(S_p\) 的最短路中,按照一下优先级的最短路径
send最少send相等,back最少
数据范围
\(1\leq n\leq 500\)
题解
- 在最短路上经过每个点时,当前的
send/back就应该能够每个节点调整至完美状态 - 每个点的
send/back都是根据上一个节点的计算而来 - 必须从
0开始计算各点的值 - 每一个节点都有后效性,所以不是最优子结构,不能用简单的 \(dp\) 或贪心计算
例子
10 4 4 4
6 7 0 6
0 1 2
1 2 2
2 3 2
3 4 2
Code
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
const int N = 510;
vector<bool> st(N);
vector<pair<int, int>> edge[N];
vector<int> C(N), dis(N), pre[N];
vector<int> path, tmp_path;
int Cmax, n, Sp, m;
int min_send = INT_MAX, min_back = INT_MAX;
void dijkstra() {
fill(dis.begin(), dis.end(), INT_MAX);
dis[0] = 0;
for (int i = 0; i < n; i++) {
int t = -1;
for (int j = 0; j <= n; j++) {
if (not st[j] and (t == -1 or dis[j] < dis[t]))
t = j;
}
st[t] = 1;
for (auto it : edge[t]) {
auto to = it.fi, w = it.se;
if (dis[to] > dis[t] + w) {
dis[to] = dis[t] + w;
pre[to].clear();
pre[to].push_back(t);
} else if (dis[to] == dis[t] + w) {
pre[to].push_back(t);
}
}
}
}
void dfs(int vertice) {
tmp_path.push_back(vertice);
if (vertice == 0) {
int send = 0, back = 0;
for (int i = tmp_path.size() - 1; i >= 0; i--) {
auto it = tmp_path[i];
if(C[it] > 0) back += C[it];
else {
if(back > abs(C[it])) {
back += C[it];
} else {
send += abs(C[it]) - back;
back = 0;
}
}
}
if(send < min_send) {
min_send = send;
path = tmp_path;
min_back = back;
}
else if(send == min_send and back < min_back) {
min_back = back;
path = tmp_path;
}
tmp_path.pop_back();
return;
}
for (auto it : pre[vertice]) dfs(it);
tmp_path.pop_back();
}
int main() {
cin >> Cmax >> n >> Sp >> m;
for (int i = 1; i <= n; i++) {
int x; cin >> x;
C[i] = x - Cmax / 2;
}
while (m--) {
int u, v, w; cin >> u >> v >> w;
edge[u].push_back({v, w});
edge[v].push_back({u, w});
}
dijkstra();
dfs(Sp);
cout << min_send << ' ';
for (int i = path.size() - 1; i >= 0; i--) {
cout << path[i];
if (i != 0) cout << "->";
else cout << ' ';
}
cout << min_back;
}

浙公网安备 33010602011771号