2018年东北农业大学春季校赛 C-wyh的商机

一天,你们wyh学长和你们zhl学长玩一个游戏,这个游戏规则是这样的

给你n个城市,保证这n个城市之间都只有一条道路可以到达。

有一件物品,在所有城市中都是一样的,但是由于各个城市的经济发展不同,导致每个城市对于这件物品销售的价格不同。

游戏一共进行Q轮。

每轮给你2个点s和t,其中s代表起点,t代表终点。

对于每一个城市都可以选择买这个物品,如果手里有这个物品的话,也可以选择卖掉这个物品,对于同一个城市来说,买和卖的价格是一样的,每一个城市只能买一件物品

现在,你们wyh学长和zhl学长都需要找到一个方案,使得从起点走到终点的时候盈利最多,请你帮助帮助他们吧。

(题意巨坑, 要求一条路径只能买卖一次。。。)

 

思路:离线, 利用tarjan离线求lca 的思想, 利用并查集维护链上的最大值, 最小值, 上升时的最大差值, 下降时的最大差值, 对于一个s, t的询问

当dfs回溯到 lca = lca(s, t) 的时候s 到 lca 和 t 到 lca 的最大值, 最小值, 上升时的最大差值, 下降时的最大差值都已经知道啦,然后就能更新答案啦。

 1 #include<bits/stdc++.h>
 2 #define LL long long
 3 #define fi first
 4 #define se second
 5 #define mk make_pair
 6 #define pii pair<int,int>
 7 using namespace std;
 8 
 9 const int N = 1e5 + 7;
10 const int M = 100 + 7;
11 const int inf = 0x3f3f3f3f;
12 const LL INF = 0x3f3f3f3f3f3f3f3f;
13 const int mod = 1e9 + 7;
14 
15 int n, m, mn[N], mx[N], up[N], down[N], ans[N], fa[N];
16 
17 bool vis[N];
18 
19 struct Qus {
20     int s, t, id;
21 };
22 
23 vector<Qus> qus[N];
24 vector<pii> Q[N];
25 vector<int> edge[N];
26 
27 
28 int Find(int x) {
29     if(fa[x] == x)
30         return x;
31     int root = Find(fa[x]);
32     up[x] = max(max(up[x], up[fa[x]]), mx[fa[x]] - mn[x]);
33     down[x] = max(max(down[x], down[fa[x]]), mx[x] - mn[fa[x]]);
34     mn[x] = min(mn[x], mn[fa[x]]);
35     mx[x] = max(mx[x], mx[fa[x]]);
36     return fa[x] = root;
37 }
38 
39 void dfs(int u) {
40     vis[u] = true;
41     for(pii v : Q[u]) {
42         if(vis[v.fi]) {
43             int lca = Find(v.fi);
44             if(v.se > 0) {
45                 qus[lca].push_back({u, v.fi, v.se});
46             } else {
47                 qus[lca].push_back({v.fi, u, -v.se});
48             }
49         }
50     }
51 
52     for(int v : edge[u]) {
53         if(!vis[v]) {
54             dfs(v);
55             fa[v] = u;
56         }
57     }
58 
59     for(Qus now : qus[u]) {
60         int x = now.s, y = now.t, id = now.id;
61         Find(x); Find(y);
62         ans[id] = max(mx[y] - mn[x], max(up[x], down[y]));
63     }
64 }
65 int main() {
66 
67     scanf("%d", &n);
68 
69     for(int i = 1; i <= n; i++) {
70         int w; scanf("%d", &w);
71         mn[i] = mx[i] = w;
72         fa[i] = i;
73     }
74 
75     for(int i = 1; i < n; i++) {
76         int u, v; scanf("%d%d", &u, &v);
77         edge[u].push_back(v);
78         edge[v].push_back(u);
79     }
80 
81     scanf("%d", &m);
82     for(int i = 1; i <= m; i++) {
83         int s, t; scanf("%d%d", &s, &t);
84         Q[s].push_back(mk(t, i));
85         Q[t].push_back(mk(s, -i));
86     }
87 
88     dfs(1);
89 
90     for(int i = 1; i <= m; i++) {
91         printf("%d\n", ans[i]);
92     }
93     return 0;
94 }
95 
96 /*
97 */

 

 

posted @ 2018-04-09 12:14  NotNight  阅读(145)  评论(0编辑  收藏  举报