在一片神奇的土地上有 n 个城市,这些城市由若干条公路连接。有些公路上有路霸,车主需交一定的过路费才能通过;有些公路上有补给站,车主可以免费获得一定价值的补给。现在给你 k 条公路的信息,每一条公路由 u,v,t,x 四个正整数描述;如果 t=1 表示城市 u 和 v 之间的公路上有路霸,需交过路费 x 才能通过;如果 t=2 表示城市 u 和 v 之间的公路上有补给站,可以免费获得价值为 x 的补给。已知所有的公路都是单向的,补给可以充抵相同金额的过路费。请问车主从城市 1 到达城市 n 最大能获得多少补给?如果一路上获得的补给大于等于一路上交的过路费,则输出一个非负整数,其值为一路上获得的补给减去一路上交的过路费;如果一路上获得的补给小于一路上交的过路费,则输出一个负整数,其绝对值为一路上交的过路费减去一路上获得的补给;如果哪怕是一路全部交过路费都无法到达城市 n ,则输出 NULL。c++
时间: 2024-03-24 21:41:18 浏览: 80
这是一个典型的最大路径问题,可以使用拓扑排序和动态规划来解决。具体来说,我们可以先对给定的图进行拓扑排序,然后按照拓扑序列的逆序进行动态规划,计算出每个城市到城市 n 的最大补给值。最终,我们只需要查找城市 1 到城市 n 的最大补给值,并将其减去城市 1 到城市 n 的最小过路费即可。
下面是一个用 C++ 实现的解决方案:
```cpp
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
const int MAXN = 1000005;
const int INF = 0x3f3f3f3f;
struct Edge {
int v, t, x;
};
vector<Edge> edges[MAXN];
int in_degree[MAXN];
int dp[MAXN];
bool vis[MAXN];
void add_edge(int u, int v, int t, int x) {
edges[u].push_back({v, t, x});
in_degree[v]++;
}
void topo_sort(int n) {
queue<int> q;
memset(dp, -1, sizeof(dp));
dp[n] = 0;
q.push(n);
while (!q.empty()) {
int u = q.front();
q.pop();
vis[u] = true;
for (auto e : edges[u]) {
int v = e.v, t = e.t, x = e.x;
if (t == 1) {
dp[v] = max(dp[v], dp[u] - x);
} else {
dp[v] = max(dp[v], dp[u] + x);
}
in_degree[v]--;
if (in_degree[v] == 0) {
q.push(v);
}
}
}
}
int main() {
int n, m;
cin >> n >> m;
while (m--) {
int u, v, t, x;
cin >> u >> v >> t >> x;
add_edge(u, v, t, x);
}
topo_sort(n);
if (!vis[1]) {
cout << "NULL" << endl;
} else {
int ans = dp[1];
for (int i = 2; i <= n; i++) {
if (!vis[i]) {
continue;
}
for (auto e : edges[i]) {
int v = e.v, t = e.t, x = e.x;
if (t == 1) {
ans = max(ans, dp[i] - dp[v] - x);
}
}
}
cout << ans << endl;
}
return 0;
}
```
其中,`n` 表示城市的数量,`m` 表示公路的数量。我们使用一个 `vector` 数组 `edges` 来存储图的信息,其中 `edges[u]` 表示以城市 `u` 为起点的所有边。同时,我们使用一个 `in_degree` 数组来记录每个城市的入度,以便进行拓扑排序。我们还使用一个 `dp` 数组来记录每个城市到城市 n 的最大补给值。最后,我们使用一个 `vis` 数组来记录每个城市是否被访问过。
在程序中,我们首先读入公路信息,并根据公路类型和费用建立有向边。接着,我们进行拓扑排序,按照拓扑序列的逆序进行动态规划,计算出每个城市到城市 n 的最大补给值。最后,我们遍历每个城市的出边,计算出城市 1 到城市 n 的最小过路费,并将其减去城市 1 到城市 n 的最大补给值即可得到最终结果。
希望这个算法能够帮助到您!
阅读全文