1. 程式人生 > >【NOIP2009提高組】最優貿易

【NOIP2009提高組】最優貿易

bfs sync out logs push_back push cin tps span

https://www.luogu.org/problem/show?pid=1073

如果他想在i點賣出,那麽就要在從1點出發到i點的路徑裏找個最便宜的買入,用Bellman-Ford求出這樣最便宜的買入價記為minp[i]。他能獲得的利潤就是price[i]-minp[i]。

但是並不是可以在所有的點都可以賣出,因為他最終要走到N,所以只有在和N聯通的點才能賣出。用從N點出發倒著的DFS/BFS記錄點i是否能到達N點。

故答案為max{price[i]-minp[i] (i點與N點聯通)}

#include <iostream>
#include <vector>
#include 
<queue> #define maxn 100005 using namespace std; const int inf = 10000; int n, m, price[maxn]; vector<int> g[maxn], gt[maxn]; int minp[maxn]; bool inque[maxn]; queue<int> q; void bellman_ford() { for (int i = 1; i <= n; i++) minp[i] = inf; minp[1] = price[1]; q.push(
1); inque[1] = true; while (!q.empty()) { int v = q.front(); q.pop(); inque[v] = false; for (int i = 0; i < g[v].size(); i++) { int w = g[v][i]; if (minp[w] > min(minp[v], price[w])) { minp[w]
= min(minp[v], price[w]); if (!inque[w]) { inque[w] = true; q.push(w); } } } } } bool avai[maxn]; void dfs(int v) { avai[v] = true; for (int i = 0; i < gt[v].size(); i++) { int w = gt[v][i]; if (!avai[w]) dfs(w); } } int main() { ios::sync_with_stdio(false); cin >> n >> m; for (int i = 1; i <= n; i++) cin >> price[i]; int u, v, z; for (int i = 1; i <= m; i++) { cin >> u >> v >> z; g[u].push_back(v); gt[v].push_back(u); if (z == 2) { g[v].push_back(u); gt[u].push_back(v); } } bellman_ford(); dfs(n); int ans = 0; for (int i = 1; i <= n; i++) { if (avai[i]) ans = max(ans, price[i] - minp[i]); } cout << ans << endl; return 0; }

【NOIP2009提高組】最優貿易