日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[CODEVS 1173] 最优贸易

發布時間:2025/3/15 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [CODEVS 1173] 最优贸易 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

描述

http://www.codevs.cn/problem/1173/


分析

官方解法

先考慮如果題目中的線路不會構成環, 那么問題可以簡化成一個DP就可以解決的問題=>
先正著DP, 找出在每個點之前可以買進的最低的價格 minp ; 再倒著DP, 統計出在每個點之后可以賣出的最高價格 maxp , 取所有點中的minp - maxp 的最大值就是最大的收益.

現在的問題就是解決環的存在, 因為有環的話沒有一個拓撲序供我們DP使用. 所以用Tarjan算法求強聯通分量縮點, 同時統計出縮點后每個點的最低買入價和最高賣出價, 重新建圖, DP即可.

PS: 不會寫……

民間解法

其實我最初想練的是官方的解法, 因為向鵬達剛講了這種方法. 結果DP寫不出來了, 就用BFS寫拓撲排序. 發現還需要寫一個逆向的拓撲排序. 寫著寫著發現沒必要縮點了, 接著就YY出了民間的兩遍SPFA的做法.
都說是SPFA, 其實我覺得也不象SPFA.
另外還需要注意不能考慮不在s-t路徑上的點, SPFA同時判即可.


代碼

381ms 10MB

#include <cstdio> #include <cstring> #include <vector> #include <queue> #include <algorithm> using namespace std;const int INF = 1e7 + 7; const int maxn = 100000 + 10;queue<int> Q; vector<int> G1[maxn], G2[maxn]; int price[maxn], minp[maxn], maxp[maxn]; bool inq[maxn], vis1[maxn], vis2[maxn];void AddEdge(int s, int t) {G1[s].push_back(t);G2[t].push_back(s); }int SPFA1(int s) {memset(inq, 0, sizeof(inq));Q.push(s); vis1[s] = inq[s] = 1; minp[s] = price[s];while(!Q.empty()) {int u = Q.front(); Q.pop();inq[u] = 0; for(int i = 0; i < G1[u].size(); i++) {int v = G1[u][i];if(minp[v] > minp[u]) {minp[v] = minp[u];if(!inq[v]) Q.push(v);if(!vis1[v]) {vis1[v] = 1;minp[v] = min(minp[v], price[v]);}}}} }int SPFA2(int s) {memset(inq, 0, sizeof(inq));Q.push(s); vis2[s] = inq[s] = 1; maxp[s] = price[s];while(!Q.empty()) {int u = Q.front(); Q.pop();inq[u] = 0; for(int i = 0; i < G2[u].size(); i++) {int v = G2[u][i];if(maxp[v] < maxp[u]) {maxp[v] = maxp[u];if(!inq[v]) Q.push(v);if(!vis2[v]) {vis2[v] = 1;maxp[v] = max(maxp[v], price[v]);}}}} }int main() {int n, m;scanf("%d%d", &n, &m);for(int i = 0; i < n; i++) {scanf("%d", &price[i]);minp[i] = INF;maxp[i] = -1;}for(int i = 0; i < m; i++) {int u, v, state;scanf("%d%d%d", &u, &v, &state);u--; v--;AddEdge(u, v);if(state == 2) AddEdge(v, u);}SPFA1(0);SPFA2(n-1);int ans = 0;for(int i = 0; i < n; i++) if(vis1[i] && vis2[i]) // 注意判斷ans = max(ans, maxp[i] - minp[i]);printf("%d\n", ans);return 0; }

總結

以上是生活随笔為你收集整理的[CODEVS 1173] 最优贸易的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。