题目相关
题目链接
AtCoder Beginner Contest 188 E 题,https://atcoder.jp/contests/abc188/tasks/abc188_e。
Problem Statement
In Takahashi Kingdom, there are
N
N
N towns, called Town
1
1
1 through Town
N
N
N.
There are also
M
M
M roads in the kingdom, called Road
1
1
1 through Road
M
M
M. By traversing Road
i
i
i, you can travel from Town
X
i
X_i
Xi to Town
Y
i
Y_i
Yi, but not vice versa. Here, it is guaranteed that
X
i
<
Y
i
X_i<Y_i
Xi<Yi.
Gold is actively traded in this kingdom. At Town
i
i
i, you can buy or sell
1
1
1 kilogram of gold for
A
i
A_i
Ai yen (the currency of Japan).
Takahashi, a traveling salesman, plans to buy
1
1
1 kilogram of gold at some town, traverse one or more roads, and sell
1
1
1 kilogram of gold at another town.
Find the maximum possible profit (that is, the selling price minus the buying price) in this plan.
Input
Input is given from Standard Input in the following format:
N M
A1 A2 ... AN
X1 Y1
X2 Y2
.
.
.
XM YM
Output
Print the answer.
Sample 1
Sample Input 1
4 3
2 3 1 5
2 4
1 2
1 3
Sample Output 1
3
Explaination
We can achieve the profit of
3
3
3 yen, as follows:
At Town
1
1
1, buy one kilogram of gold for
2
2
2 yen.
Traverse Road
2
2
2 to get to Town
2
2
2.
Traverse Road
1
1
1 to get to Town
4
4
4.
At Town
4
4
4, sell one kilogram of gold for
5
5
5 yen.
Sample 2
Sample Input 2
5 5
13 8 3 15 18
2 4
1 2
4 5
2 3
1 3
Sample Output 2
10
Explaination
We can achieve the profit of
10
10
10 yen, as follows:
At Town
2
2
2, buy one kilogram of gold for
8
8
8 yen.
Traverse Road
1
1
1 to get to Town
4
4
4.
Traverse Road
3
3
3 to get to Town
5
5
5.
At Town
5
5
5, sell one kilogram of gold for
18
18
18 yen.
Sample 3
Sample Input 3
3 1
1 100 1
2 3
Sample Output 3
-99
Explaination
Note that we cannot sell gold at the town where we bought the gold, which means the answer may be negative.
Constraints
- 2 ≤ N ≤ 2 × 1 0 5 2≤N≤2×10^5 2≤N≤2×105
- 1 ≤ M ≤ 2 × 1 0 5 1≤M≤2×10^5 1≤M≤2×105
- 1 ≤ A i ≤ 1 0 9 1≤A_i≤10^9 1≤Ai≤109
- 1 ≤ X i < Y i ≤ N 1≤Xi<Yi≤N 1≤Xi<Yi≤N
- ( X i , Y i ) ≠ ( X j , Y j ) ( i ≠ j ) (Xi,Yi)≠(Xj,Yj)(i≠j) (Xi,Yi)=(Xj,Yj)(i=j)
- All values in input are integers.
题解报告
题目翻译
在高桥的王国,有
N
N
N 个城镇,编号从
1
1
1 到
N
N
N。
在王国里有
M
M
M 条道路,称为道路
1
1
1 到道路
M
M
M。穿过第
i
i
i 条道路,可以从城镇
X
i
X_i
Xi 到城镇
Y
i
Y_i
Yi,但是这第
i
i
i 条道路,不会从城镇
Y
i
Y_i
Yi 到
X
i
X_i
Xi。
在王国里,黄金交易非常活跃。在城镇
i
i
i,你可以使用
A
i
A_i
Ai 日圆购买
1
1
1 公斤黄金。
高桥,一个旅行商,计划在某个城镇买
1
1
1 公斤黄金,通过一条或者多条道路,在其他城镇卖出这些黄金。
请找出最大的收益。
题目分析
根据题目的描述,找出最大值,基本上就是一个动态规划题目。虽然本题看起来像是数据结构图论方面的内容,DAG 问题。
由于本题有一个限制,也就是
1
≤
X
i
<
Y
i
≤
N
1≤Xi<Yi≤N
1≤Xi<Yi≤N,我们可以从
N
N
N 到
1
1
1 进行动态规划。
假设
D
P
[
i
]
DP[i]
DP[i] 为第
i
i
i 个城镇可以到达的所有城镇中黄金价格最高,不包括第
i
i
i 个城镇。ans 为 dp[i]-a[i] 的最大值。
样例 1 数据分析
根据样例数据,我们可以绘制出如下的图。
上图中,黑色表示城镇编号,绿色表示道路,红色表示这个城镇黄金价格。这样我们将有以下两个数据结构,第一个为黄金价格表
a
a
a。
a[i] | 数值 |
---|---|
1 | 2 |
2 | 3 |
3 | 1 |
4 | 5 |
一个是连接矩阵 a d j adj adj。
adj[i] | 值 |
---|---|
1 | 2 |
3 | |
2 | 4 |
对应的 D P DP DP 数组初始化值都是 -1e9。这样我们从 N N N 到 1 1 1 ,寻找第 i i i 个城镇相邻的城镇最高黄金价格。如果第 i i i 个城镇没有相连的城镇,就吧 D P DP DP 数组对应值写为 a [ i ] a[i] a[i]。
第 4 4 4 个城镇
由于没有相连的城镇,DP[4]=a[4]。这样 D P DP DP 数组的值变为
DP[i] | 数值 | ans |
---|---|---|
1 | -1e9 | -1e9 |
2 | -1e9 | – |
3 | -1e9 | – |
4 | 5 | – |
第 3 3 3 个城镇
由于没有相连的城镇,DP[3]=a[3]。这样 D P DP DP 数组的值变为
DP[i] | 数值 | ans |
---|---|---|
1 | -1e9 | -1e9 |
2 | -1e9 | |
3 | 1 | |
4 | 5 |
第 2 2 2 个城镇
该城镇可以到城镇 4 4 4,因此,我们取 DP[2] 和 DP[5] 的最大值,也就是 DP[5],即 DP[2]=5。ans 的值也发生改变,变为 max(ans, DP[2]-a[2]),也就是在 2 2 2 城镇买, 5 5 5 城镇卖的差价,也就是 5 − 3 = 2 5-3=2 5−3=2。
DP[i] | 数值 | ans |
---|---|---|
1 | -1e9 | 2 |
2 | 5 | |
3 | 1 | |
4 | 5 |
第 1 1 1 个城镇
该城镇可以到城镇 2 2 2 和 3 3 3。我们先到城镇 2 2 2,这样 D P [ 1 ] = m a x ( D P [ 1 ] , D P [ 2 ] ) = 5 DP[1]=max(DP[1], DP[2])=5 DP[1]=max(DP[1],DP[2])=5。再到城镇 3 3 3,这样 D P [ 1 ] = m a x ( D P [ 1 ] , D P [ 3 ] ) = 5 DP[1]=max(DP[1], DP[3])=5 DP[1]=max(DP[1],DP[3])=5。这样遍历完连接表,表示从 1 1 1 连接的城镇最高黄金价格为 5 5 5。因此,我们从 1 1 1 城镇购买黄金,到其他城镇卖出,可以获得的价差为 5 − 2 = 3 5-2=3 5−2=3,跟新 ans 的数据。
DP[i] | 数值 | ans |
---|---|---|
1 | 5 | 3 |
2 | 5 | |
3 | 1 | |
4 | 5 |
数据范围估计
从上面分析中,我们只有减法,而且 A i A_i Ai 的最大数据为 1 0 9 10^9 109,因此 int 可以。
AC 代码
//https://atcoder.jp/contests/abc188/tasks/abc188_e
//E - Peddler Editorial
#include <bits/stdc++.h>
using namespace std;
//如果提交到OJ,不要定义 __LOCAL
//#define __LOCAL
typedef long long ll;
int main() {
#ifndef __LOCAL
//这部分代码需要提交到OJ,本地调试不使用
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#endif
ll n, m;
cin>>n>>m;
vector<int> a(n+1);
for (int i=1; i<=n; i++) {
cin>>a[i];
}
//连接表
vector<vector<int>> adj(n+1);
for (int i=1; i<=m; i++) {
int u,v;
cin>>u>>v;
//建立连接表
adj[u].emplace_back(v);
}
vector<int> dp(n+1, -1e9);//最高价格
int ans=-1e9;
for (int i=n; i>=1; i--) {
//在 adj[i] 中遍历找出黄金最高价
for (int j=0; j<adj[i].size(); j++){
dp[i] = max(dp[i], dp[adj[i][j]]);
}
ans = max(ans, dp[i]-a[i]);
dp[i] = max(dp[i], a[i]);//更新价格
}
cout<<ans<<"\n";
#ifdef __LOCAL
//这部分代码不需要提交到OJ,本地调试使用
system("pause");
#endif
return 0;
}
时间复杂度
O ( N + M ) O(N+M) O(N+M)。
空间复杂度
O ( N ) O(N) O(N)。