poj3728

来源:互联网 发布:mac版pr快捷键 编辑:程序博客网 时间:2024/06/07 03:14

题链http://poj.org/problem?id=3728

题述:一个树有N个节点,每个节点都有同一件物品,但不同的节点价格不相同,给出每个节点的价钱,Q次询问x,y对于每次询问求从x到y进行一次买卖最大可以获取的利润。

样例

Sample Input

41 5 3 21 33 23 491 21 31 42 32 12 43 13 23 4

Sample Output

422000020
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cmath>#include <cstdlib>using namespace std;const int inf=20000000, N=50010;struct edge{  int v,id,nx;}e[3][N*2];int i,n,m,size,u,v,head[3][N];int uu[N],vv[N],w[N],ans[N],up[N],down[N],maxw[N],minw[N],f[N];bool b[N];void add(int u,int v,int id,int p){  size++; e[p][size].v=v; e[p][size].id=id;  e[p][size].nx=head[p][u]; head[p][u]=size;}void init(){  size=0;  for(i=0;i<=n;i++)  {    head[0][i]=head[1][i]=head[2][i]=-1;     b[i]=false;  }  for(i=1;i<=n;i++)  {    scanf("%d",&w[i]);    up[i]=down[i]=0;    maxw[i]=minw[i]=w[i];  }  for(i=1;i<n;i++)  {    scanf("%d%d",&u,&v);    add(u,v,i,0);     add(v,u,i,0);  }  size=0; scanf("%d",&m);  for(i=1;i<=m;i++)  {    scanf("%d%d",&uu[i],&vv[i]);    add(uu[i],vv[i],i,1);     add(vv[i],uu[i],i,1);  }}int Max(int a,int b){  return (a>b)?a:b;}int Min(int a,int b){  return (a<b)?a:b;}int find(int v){    if (v==f[v]) return f[v];  int fa=f[v];   f[v]=find(f[v]);  up[v]=Max(Max(up[v],up[fa]),maxw[fa]-minw[v]);  down[v]=Max(Max(down[v],down[fa]),maxw[v]-minw[fa]);  maxw[v]=Max(maxw[v],maxw[fa]);  minw[v]=Min(minw[v],minw[fa]);  return f[v];}void lca(int u){  int i,v,id,fa;  b[u]=true;   f[u]=u;  i=head[1][u];  while (i!=-1)  {    v=e[1][i].v; id=e[1][i].id;    if (b[v])    {      fa=find(v);      add(fa,v,id,2);    }    i=e[1][i].nx;  }  i=head[0][u];  while (i!=-1)  {    v=e[0][i].v;    if (!b[v])    {      lca(v);       f[v]=u;    }    i=e[0][i].nx;  }  i=head[2][u];  while (i!=-1)  {    id=e[2][i].id;    find(uu[id]); find(vv[id]);    ans[id]=Max(Max(up[uu[id]],down[vv[id]]),maxw[vv[id]]-minw[uu[id]]);    i=e[2][i].nx;  }}int main(){  while (scanf("%d",&n)==1)  {    init();    size=0; lca(1);    for(i=1;i<=m;i++) printf("%d\n",ans[i]);  }  return 0;}