• 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
    ", ans[i]);
    92     }
    93     return 0;
    94 }
    95 
    96 /*
    97 */
  • 相关阅读:
    C#基础第五天-作业-用DataTable制作名片集
    C#基础第四天-作业答案-Hashtable-list<KeyValuePair>泛型实现名片
    C#基础第四天-作业-Hashtable-list<KeyValuePair>泛型实现名片
    C#基础第三天-作业答案-集合-冒泡排序-模拟名片
    C#基础第三天-作业-集合-冒泡排序-模拟名片
    C#基础第二天-作业答案-九九乘法表-打印星星
    C#基础第二天-作业-九九乘法表-打印星星
    C#基础第一天-作业答案
    C#基础第一天-作业
    C#-string.Format对C#字符串格式化
  • 原文地址:https://www.cnblogs.com/CJLHY/p/8758984.html
Copyright © 2020-2023  润新知