长沙免费模板建站,wordpress推荐形式模版,ip地址域名解析,阳西网站建设341. 最优贸易 - AcWing题库
C 国有 n 个大城市和 m 条道路#xff0c;每条道路连接这 n 个城市中的某两个城市。
任意两个城市之间最多只有一条道路直接相连。
这 m 条道路中有一部分为单向通行的道路#xff0c;一部分为双向通行的道路#xff0c;双向通行的道路在统计…341. 最优贸易 - AcWing题库
C 国有 n 个大城市和 m 条道路每条道路连接这 n 个城市中的某两个城市。
任意两个城市之间最多只有一条道路直接相连。
这 m 条道路中有一部分为单向通行的道路一部分为双向通行的道路双向通行的道路在统计条数时也计为 1 条。
C 国幅员辽阔各地的资源分布情况各不相同这就导致了同一种商品在不同城市的价格不一定相同。
但是同一种商品在同一个城市的买入价和卖出价始终是相同的。
商人阿龙来到 C 国旅游。
当他得知“同一种商品在不同城市的价格可能会不同”这一信息之后便决定在旅游的同时利用商品在不同城市中的差价赚一点旅费。
设 C 国 n 个城市的标号从 1∼n阿龙决定从 1 号城市出发并最终在 n 号城市结束自己的旅行。
在旅游的过程中任何城市可以被重复经过多次但不要求经过所有 n 个城市。
阿龙通过这样的贸易方式赚取旅费他会选择一个经过的城市买入他最喜欢的商品——水晶球并在之后经过的另一个城市卖出这个水晶球用赚取的差价当做旅费。
因为阿龙主要是来 C 国旅游他决定这个贸易只进行最多一次当然在赚不到差价的情况下他就无需进行贸易。
现在给出 n 个城市的水晶球价格m 条道路的信息每条道路所连接的两个城市的编号以及该条道路的通行情况。
请你告诉阿龙他最多能赚取多少旅费。
注意本题数据有加强。
输入格式
第一行包含 2 个正整数 n 和 m中间用一个空格隔开分别表示城市的数目和道路的数目。
第二行 n 个正整数每两个整数之间用一个空格隔开按标号顺序分别表示这 n 个城市的商品价格。
接下来 m 行每行有 33 个正整数xyz每两个整数之间用一个空格隔开。
如果 z1表示这条道路是城市 x 到城市 y 之间的单向道路如果 z2表示这条道路为城市 x 和城市 y 之间的双向道路。
输出格式
一个整数表示答案。
数据范围
1≤n≤100000 1≤m≤500000 1≤各城市水晶球价格≤100
输入样例
5 5
4 3 5 6 1
1 2 1
1 4 1
2 3 2
3 5 1
4 5 2输出样例
5
解析
本题做法有很多可以使用分层图来处理这里使用dp的方式处理。
状态划分不重不漏将状态转移所依据的状态体现出来
fmax[i], fmin[i] 表示路径上买和卖的分界点为 i 时买入的最小值为fmin[i],卖出的最大值为fmax[i]
那么最终的结果就为 max{fmax[i]-fmin[i]}。
状态转移方程为fmin[k]min(fmin[j]……wk)
fmax[k]的状态转移方程类似。
本质上是个dp问题由于本题中的图可能是有环的即dp的状态转移是环形的具有后效性所以我们需要将其转换最短路问题进行处理对于环形dp可查看dp专栏
本题要有一点特别的地方是本题边的权值在点上而不在边上。仔细观察可以发现本题是不能使用Dijkstra 算法的因为从公式fmin[k]min(fmin[j]……wk)可以看出来如果使用Dijkstra算法当存在环时已经更新过的点还有可能被更新等价于有负权边换句话说路径上的最小距离不单调递增。所以我们只能使用bellman_ford算法或其升级版算法spfa算法。
dp相当于求拓扑图上的最短路。spfa可以求任意图上的最短路。
#includeiostream
#includestring
#includecstring
#includecmath
#includectime
#includealgorithm
#includeutility
#includestack
#includequeue
#includevector
#includeset
#includemath.h
#includemap
#includesstream
#includedeque
#includeunordered_map
using namespace std;
typedef pairdouble, int PDI;
typedef pairint, int PII;
const int N 1e5 5, M 2e6 5, INF 0x3f3f3f3f;
int n, m;
int ht[N], hs[N], e[M], ne[M], idx;
int w[N], dmin[N], dmax[N];
int q[N];
int vis[N];void add(int h[], int a, int b) {e[idx] b, ne[idx] h[a], h[a] idx;
}void spfa(int h[], int dist[], int type) {int hh 0, tt 1;if (type0) {memset(dist, 0x3f, sizeof dmin);dist[1] w[1];q[0] 1;}else {memset(dist, 0, sizeof dmax);dist[n] w[n];q[0] n;}while (hh ! tt) {int t q[hh];if (hh N)hh 0;vis[t] 0;for (int i h[t]; i ! -1; i ne[i]) {int j e[i];if (type 0 dist[j]min(dist[t], w[j]) || type 1 dist[j]max(dist[t], w[j])) {if (type 0) {dist[j] min(dist[t], w[j]);}else {dist[j] max(dist[t], w[j]);}if (vis[j] 0) {q[tt] j;if (tt N)tt 0;vis[j] 1;}}}}
}int main() {scanf(%d%d, n, m);for (int i 1; i n; i) {scanf(%d, w[i]);}memset(hs, -1, sizeof hs);memset(ht, -1, sizeof ht);for (int i 1,a,b,c; i m; i) {scanf(%d%d%d, a, b,c);add(hs, a, b), add(ht, b, a);if (c 2) {add(hs, b, a), add(ht, a, b);}}spfa(hs, dmin, 0);spfa(ht, dmax, 1);int ret 0;for (int i 1; i n; i) {ret max(dmax[i] - dmin[i], ret);}cout ret endl;return 0;
}