zoukankan      html  css  js  c++  java
  • poj3728 The merchant

    题目:The merchant

    题目描述:给出一棵有n个带权(price)节点的树(结点数n<=50000),给出m组询问{v,u},询问从v到u中差最多是多少(询问次数m<=50000)。

    分析:

      (1)算法一:最朴素的方法是从v到u完整的访问一遍,枚举一个在{v,u}这条路径上的点o作为卖出点x,求出{v,o}这条路的最小值y作为买入点,{x-y}的最大值即为所求结果。

      (2)分析算法一:对于{v,o}这条路的最小值y,要使得{y-x}最大,那x必然是{o.u}的最大值。{v,u}中的差必然是{v,o}的差、{o,u}的差、{o.u}的最大值-{v,o}的最小值中取最大值。可以采取分治算法。

      (3)算法二:把{v,u}的最近公共祖先lca最作为o分治算法的分割点。{v,u}中的差是{v,lca}的差、{lca,u}的差、{lca.u}的最大值-{v,lca}的最小值中取最大值。问题转化为快速计算{v,lca}的差,{lca,u}的差,{lca,u}的最大值,{v,lca}的最小值,仍然采用分治思想,利用倍增进行预处理和加速计算。

      (4)算法三:由于询问没有相关性,而且所有询问在一开始就已经知道,可以离线计算。采用Tarjan算法,用并查集维护{v,lca}的差,{lca,u}的差,{lca,u}的最大值,{v,lca}的最小值。

      (5)算法二和算法三均利用了分析二的思路。

      (6)扩展:问题中的树如果退化成一条链,有其他做法。用一个新序列$w_2-w_1,w_3-w_2 ,cdots, w_n-w_{n-1}$,这样只需要求得询问区间最大子段和即为结果Max-Min了,可以采用线段树去加速计算,做法类似{USACO 2008 Feb Hotel}一题。

    代码:

    算法二:

     1 #include <cstdio>
     2 #include <algorithm>
     3 const int Inf=1e9;
     4 int Tval[50005],Tdep[50005],Tfa[50005][21];
     5 int Tmin[50005][21],Tmax[50005][21],Tup[50005][21],Tdown[50005][21];
     6 int size,first[50005];
     7 struct Edge{int to,next;}e[100005];
     8 int Read(){
     9     int ch='@',t=0;
    10     for(;ch<48 || 57<ch;ch=getchar());
    11     for(;47<ch && ch<58;ch=getchar())t=t*10+ch-48;
    12     return t;
    13 } 
    14 inline int max(int x,int y) {x-=y;return y+(x&(~(x>>31)));}
    15 inline int min(int x,int y) {x-=y;return y+(x&(x>>31));}
    16 void addedge(int x,int y){
    17     e[++size].to=y;e[size].next=first[x];first[x]=size;
    18     e[++size].to=x;e[size].next=first[y];first[y]=size;
    19 }
    20 void LcaInit(int v){
    21     for(int i=1,j,k,tv;i<17;++i){
    22         Tfa[v][i]=Tfa[Tfa[v][i-1]][i-1];
    23         Tmin[v][i]=min(Tmin[v][i-1],Tmin[Tfa[v][i-1]][i-1]);
    24         Tmax[v][i]=max(Tmax[v][i-1],Tmax[Tfa[v][i-1]][i-1]);
    25         Tup[v][i]=max(max(Tup[v][i-1],Tup[Tfa[v][i-1]][i-1]),Tmax[Tfa[v][i-1]][i-1]-Tmin[v][i-1]);
    26         Tdown[v][i]=max(max(Tdown[v][i-1],Tdown[Tfa[v][i-1]][i-1]),Tmax[v][i-1]-Tmin[Tfa[v][i-1]][i-1]);
    27     }
    28     for(int i=first[v],u;i;i=e[i].next){
    29         u=e[i].to;if(u==Tfa[v][0])continue;
    30         Tfa[u][0]=v;
    31         Tdep[u]=Tdep[v]+1;
    32         Tmin[u][0]=min(Tval[u],Tval[v]);
    33         Tmax[u][0]=max(Tval[u],Tval[v]);
    34         Tup[u][0]=max(0,Tval[v]-Tval[u]);
    35         Tdown[u][0]=max(0,Tval[u]-Tval[v]);
    36         LcaInit(u);
    37     }
    38 }
    39 int GetLca(int v,int u){
    40     if(Tdep[v]<Tdep[u])std::swap(v,u);
    41     for(int i=16;i>=0;--i)
    42         if((Tdep[v]-Tdep[u])&(1<<i))v=Tfa[v][i];
    43     if(v==u)return v;
    44     for(int i=16;i>=0;--i)
    45         if(Tfa[v][i]!=Tfa[u][i]){v=Tfa[v][i];u=Tfa[u][i];}
    46     return Tfa[v][0];
    47 }
    48 int GetAns(int v,int u){
    49     int lca=GetLca(v,u);
    50     int Min=Inf,Max=0,ans=0;
    51     for(int i=16;i>=0;--i)
    52         if((Tdep[v]-Tdep[lca])&(1<<i)){
    53             ans=max(ans,max(Tup[v][i],Tmax[v][i]-Min));
    54             Min=min(Min,Tmin[v][i]);
    55             v=Tfa[v][i];
    56         }
    57     for(int i=16;i>=0;--i)
    58         if((Tdep[u]-Tdep[lca])&(1<<i)){
    59             ans=max(ans,max(Tdown[u][i],Max-Tmin[u][i]));
    60             Max=max(Max,Tmax[u][i]);
    61             u=Tfa[u][i];
    62         }
    63     return max(ans,Max-Min);
    64 }
    65 int main(){
    66     //freopen("in.txt","r",stdin);
    67     //freopen("out.txt","w",stdout);
    68     int n,q;
    69     n=Read();
    70     for(int i=1;i<=n;++i)
    71         Tval[i]=Read();
    72     for(int i=1,a,b;i<n;++i){
    73         a=Read();b=Read();
    74         addedge(a,b);
    75     }
    76     LcaInit(1);
    77     q=Read();
    78     for(int i=1,a,b,ans;i<=q;++i){
    79         a=Read();b=Read();
    80         ans=GetAns(a,b);
    81         printf("%d
    ",ans);
    82     }
    83     //fclose(stdin);fclose(stdout);
    84     return 0;
    85 }

    算法三:

     1 #include <cstdio>
     2 #include <algorithm>
     3 const int Inf=1e9;
     4 int Rt[50005];
     5 bool vis[50005];
     6 int Tmin[50005],Tmax[50005],Tup[50005],Tdown[50005];
     7 int Gsize,Qsize,Asize,Gfirst[50005],Qfirst[50005],Afirst[50005];
     8 struct GEdge{int to,next;}Ge[100005];
     9 struct QEdge{int to,id,next;}Qe[100005];
    10 struct AEdge{int id,next;}Ae[100005];
    11 struct Query{int u,v,ans;}Que[100005];
    12 int Read(){
    13     int ch='@',t=0;
    14     for(;ch<48 || 57<ch;ch=getchar());
    15     for(;47<ch && ch<58;ch=getchar())t=t*10+ch-48;
    16     return t;
    17 } 
    18 inline int max(int x,int y) {x-=y;return y+(x&(~(x>>31)));}
    19 inline int min(int x,int y) {x-=y;return y+(x&(x>>31));}
    20 void Gaddedge(int x,int y){
    21     Ge[++Gsize].to=y;Ge[Gsize].next=Gfirst[x];Gfirst[x]=Gsize;
    22     Ge[++Gsize].to=x;Ge[Gsize].next=Gfirst[y];Gfirst[y]=Gsize;
    23 }
    24 void Qaddedge(int x,int y,int id){
    25     Qe[++Qsize].to=y;Qe[Qsize].id=id;Qe[Qsize].next=Qfirst[x];Qfirst[x]=Qsize;
    26     Qe[++Qsize].to=x;Qe[Qsize].id=id;Qe[Qsize].next=Qfirst[y];Qfirst[y]=Qsize;
    27 }
    28 void Aaddedge(int x,int id){
    29     Ae[++Asize].id=id;Ae[Asize].next=Afirst[x];Afirst[x]=Asize;
    30 }
    31 int GetRt(int v){
    32     if(Rt[v]==v)return v;
    33     int fa=Rt[v];
    34     Rt[v]=GetRt(Rt[v]);
    35     Tup[v]=max(max(Tup[v],Tup[fa]),Tmax[fa]-Tmin[v]);
    36     Tdown[v]=max(max(Tdown[v],Tdown[fa]),Tmax[v]-Tmin[fa]);
    37     Tmin[v]=min(Tmin[v],Tmin[fa]);
    38     Tmax[v]=max(Tmax[v],Tmax[fa]);
    39     return Rt[v];
    40 }
    41 void Tarjan(int v){
    42     vis[v]=true;
    43     for(int i=Qfirst[v],u,lca;i;i=Qe[i].next){
    44         u=Qe[i].to;if(!vis[u])continue;
    45         lca=GetRt(u); 
    46         Aaddedge(lca,Qe[i].id);
    47     }
    48     for(int i=Gfirst[v],u;i;i=Ge[i].next){
    49         u=Ge[i].to;if(vis[u])continue;
    50         Tarjan(u);
    51         Rt[u]=v;
    52     }
    53     for(int i=Afirst[v],id,tv,tu;i;i=Ae[i].next){
    54         id=Ae[i].id;tv=Que[id].v;tu=Que[id].u;
    55         GetRt(tv);GetRt(tu);
    56         Que[id].ans=max(max(Tup[tv],Tdown[tu]),Tmax[tu]-Tmin[tv]);
    57     }
    58 }
    59 int main(){
    60     //freopen("in.txt","r",stdin);
    61     //freopen("out.txt","w",stdout);
    62     int n,q;
    63     n=Read();
    64     for(int i=1;i<=n;++i)
    65         Rt[i]=i;
    66     for(int i=1;i<=n;++i)
    67         Tmin[i]=Tmax[i]=Read();
    68     for(int i=1,a,b;i<n;++i){
    69         a=Read();b=Read();
    70         Gaddedge(a,b);
    71     }
    72     q=Read();
    73     for(int i=1;i<=q;++i){
    74         Que[i].v=Read();Que[i].u=Read();
    75         Qaddedge(Que[i].v,Que[i].u,i);
    76     }
    77     Tarjan(1);
    78     for(int i=1;i<=q;++i)
    79         printf("%d
    ",Que[i].ans);
    80     //fclose(stdin);fclose(stdout);
    81     return 0;
    82 }
  • 相关阅读:
    mybatis中_parameter使用和常用sql
    ibatis中井号跟美元符号区别(#.$)
    mybatis动态sql中的trim标签的使用
    c语言捕捉异常
    lua lua解读
    lua luaconf解读
    android堆栈调试--详细
    cocos2d-x安卓应用启动调用过程简析
    ndk-stack使用方法
    cocos2dx3.2移植android
  • 原文地址:https://www.cnblogs.com/hjj1871984569/p/6005578.html
Copyright © 2011-2022 走看看