zoukankan      html  css  js  c++  java
  • poj3728 商务旅行

    [Description]
    小 T 要经常进行商务旅行,他所在的国家有 N 个城镇,标号为 1,2,3,...,N,这 N 个城镇构
    成一棵树。每个城镇可以买入和卖出货物,同一城镇买入和卖出的价格一样,小 T 想从 a
    走到 b,在这过程中,在某个城镇买入一个货物,然后在一个城镇卖出,可以是同一城镇买
    入和卖出,使得收益最大,注意不能走回头路。
    [Input]
    第一行一个数 N,第二行 N 个数,第 i 个数表示城镇 i 买入和卖出货物的价格。
    接下来 N – 1 行,每行两个数 a,b,表示 a 到 b 之间有一条双向的道路。
    接下一行一个数 Q,表示有 Q 个询问,接下来 Q 行,每行两个数 x,y,表示要求小 T 从 x
    到 y 的最大收益。
    [Output]
    对于每个询问,给出一个答案,各占一行。
    [Sample Input]
    10
    16 5 1 15 15 1 8 9 9 15
    1 2
    1 3
    2 4
    2 5
    2 6
    6 7
    4 8
    1 9
    1 10
    6
    9 1
    5 1
    1 7
    3 3
    1 1
    3 6

    [Sample Output]
    7
    11
    7
    0
    0
    15
    [Hint]
    对于 50%的数据,0 < n <= 1000,0 < m <= 100
    对于 100%的数据,0 < n <= 100000,0 < m <= 10000,0 <= 货物的价格 <= 10^8

    设 fa[i][j]表示点 i 的第 2^j 个祖先
    ma[i][j]表示点 i 到点 fa[i][j]的最大值。
    mi[i][j]表示点 i 到点 fa[i][j]的最小值。
    up[i][j]表示点 i 到点 fa[i][j]的最大获利。
    down[i][j]表示点 fa[i][j]到点 i 的最大获利。
    然后我们可以预处理出这四个数组。
    即:
    ma[x][i]=max(ma[fa[x][i-1]][i-1],ma[x][i-1]);
    mi[x][i]=min(mi[fa[x][i-1]][i-1],mi[x][i-1]);
    up[x][i]=max(max(up[fa[x][i-1]][i-1],up[x][i-1]),ma[fa[x][i-1]][i-1]-mi[x][i-1]);
    down[x][i]=max(max(down[fa[x][i-1]][i-1],down[x][i-1]),ma[x][i-1]-mi[fa[x][i-1]][i-1]);

    在走向最近公共祖先的路径上记录一下历史最小值,在远离最近公共祖先的路径上记录一下历史最大值(在途中和最大获利比较)。最后答案再和历史最大值-历史最小值比较一下即可

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 struct Node
      7 {
      8   int next,to;
      9 }edge[300001];
     10 int head[100001],num,ans,dep[100001],val[100001],flag,n,Q;
     11 int fa[100001][19],Min[100001][19],Max[100001][19],Up[100001][19],Down[100001][19];
     12 void add(int u,int v)
     13 {
     14   num++;
     15   edge[num].next=head[u];
     16   head[u]=num;
     17   edge[num].to=v;
     18 }
     19 void dfs(int x,int pa)
     20 {int i;
     21   if (dep[x]) return;
     22   dep[x]=dep[pa]+1;
     23   for (i=1;i<=18;i++)
     24     {
     25       fa[x][i]=fa[fa[x][i-1]][i-1];
     26       Max[x][i]=max(Max[x][i-1],Max[fa[x][i-1]][i-1]);
     27       Min[x][i]=min(Min[x][i-1],Min[fa[x][i-1]][i-1]);
     28       Up[x][i]=max(Up[x][i-1],Up[fa[x][i-1]][i-1]);
     29       Up[x][i]=max(Up[x][i],Max[fa[x][i-1]][i-1]-Min[x][i-1]);
     30       Down[x][i]=max(Down[x][i-1],Down[fa[x][i-1]][i-1]);
     31       Down[x][i]=max(Down[x][i],Max[x][i-1]-Min[fa[x][i-1]][i-1]);
     32     }
     33   for (i=head[x];i;i=edge[i].next)
     34     {
     35       int v=edge[i].to;
     36       if (v!=pa)
     37     {
     38       Max[v][0]=max(val[v],val[x]);
     39       Min[v][0]=min(val[v],val[x]);
     40       Up[v][0]=max(0,val[x]-val[v]);
     41       Down[v][0]=max(0,val[v]-val[x]);
     42       fa[v][0]=x;
     43       dfs(v,x);
     44     }
     45     }
     46 }
     47 int LCA(int x,int y)
     48 {
     49   int i;
     50   if (dep[x]<dep[y]) swap(x,y);
     51   for (i=18;i>=0;i--)
     52     if ((1<<i)<=dep[x]-dep[y]) 
     53       {
     54     x=fa[x][i];
     55       }
     56   if (x==y) 
     57     {
     58       //cout<<"LCA:"<<' '<<x<<endl;
     59       return x;
     60     }
     61   for (i=18;i>=0;i--)
     62     if (fa[x][i]!=fa[y][i])
     63       {
     64     x=fa[x][i];
     65     y=fa[y][i];
     66       }
     67     x=fa[x][0];
     68     y=fa[y][0];
     69     //cout<<"LCA:"<<' '<<x<<endl;
     70     return x;
     71 }
     72 void get_ans(int x,int y,int lca)
     73 {int i;
     74   int a=0,b=0,minv=2e9,maxv=0;
     75   int small=2e9,large=0;
     76   for (i=18;i>=0;i--)
     77     if ((1<<i)<=dep[x]-dep[lca])
     78       {
     79     b=max(b,Up[x][i]);
     80     b=max(b,Max[x][i]-small);
     81     small=min(small,Min[x][i]);
     82     minv=min(minv,Min[x][i]);
     83     x=fa[x][i];
     84       }
     85   for (i=18;i>=0;i--)
     86     if ((1<<i)<=dep[y]-dep[lca])
     87       {
     88     a=max(a,Down[y][i]);
     89     a=max(a,large-Min[y][i]);
     90     large=max(large,Max[y][i]);
     91     maxv=max(maxv,Max[y][i]);
     92     y=fa[y][i];
     93       }
     94   ans=max(a,max(b,maxv-minv));
     95   return;
     96 }
     97 int main()
     98 {int i,u,v,x,y;
     99   freopen("business.in","r",stdin);
    100   freopen("business.out","w",stdout);
    101   cin>>n;
    102   memset(Min,127,sizeof(Min));
    103   for (i=1;i<=n;i++)
    104     scanf("%d",&val[i]);
    105   for (i=1;i<n;i++)
    106     {
    107       scanf("%d%d",&u,&v);
    108       add(u,v);add(v,u);
    109     }
    110   dfs(1,0);
    111   cin>>Q;
    112   while (Q--)
    113     {
    114       scanf("%d%d",&x,&y);
    115       if (x==y) printf("0
    ");
    116       else 
    117       {
    118       int lca=LCA(x,y);
    119       get_ans(x,y,lca);
    120       printf("%d
    ",ans);
    121       }
    122     }
    123 }
  • 相关阅读:
    python编码的那些事
    算法基础与排序
    排序算法之low B三人组
    Django之反向生成url
    ipython的用法详解
    python3的zip函数
    Django中url的生成过程详解
    Django的ORM实现数据库事务操作
    Django的admin.py注册流程
    Django跨域请求之JSONP和CORS
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7662187.html
Copyright © 2011-2022 走看看