您的位置:首页 > 其它

Codevs 3305 水果姐逛水果街Ⅱ 倍增LCA

2016-03-14 14:57 417 查看
题目:http://codevs.cn/problem/3305/
时间限制: 2 s

空间限制: 256000 KB

题目等级 : 钻石 Diamond

题解

题目描述 Description

水果姐第二天心情也很不错,又来逛水果街。

突然,cgh又出现了。cgh施展了魔法,水果街变成了树结构(店与店之间只有一条唯一的路径)。

同样还是n家水果店,编号为1~n,每家店能买水果也能卖水果,并且同一家店卖与买的价格一样。

cgh给出m个问题,每个问题要求水果姐从第x家店出发到第y家店,途中只能选一家店买一个水果,然后选一家店(可以是同一家店,但不能往回走)卖出去。求最多可以赚多少钱。

水果姐向学过oi的你求助。

输入描述 Input Description

第一行n,表示有n家店

下来n个正整数,表示每家店一个苹果的价格。

下来n-1行,每行两个整数x,y,表示第x家店和第y家店有一条边。

下来一个整数m,表示下来有m个询问。

下来有m行,每行两个整数x和y,表示从第x家店出发到第y家店。

输出描述 Output Description

有m行。

每行对应一个询问,一个整数,表示面对cgh的每次询问,水果姐最多可以赚到多少钱。

样例输入 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

数据范围及提示 Data Size & Hint

0<=苹果的价格<=10^8

0<n<=200000

0<m<=10000

题解:
和3304同理,改为树上倍增即可。
处理信息特别麻烦。。。

代码略丑。。。

#include<bits/stdc++.h>
using namespace std;
#define MAXN 200010
#define INF 1e9
struct node
{
int begin,end,next;
}edge[MAXN*2];
int cnt,Head[MAXN],n,P[MAXN][18],mx[MAXN][18],mn[MAXN][18],lc[MAXN][18],rc[MAXN][18],deep[MAXN],a[MAXN];
bool vis[MAXN];
void addedge(int bb,int ee)
{
edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].next=Head[bb];Head[bb]=cnt;
}
void addedge1(int bb,int ee)
{
addedge(bb,ee);addedge(ee,bb);
}
int read()
{
int s=0,fh=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
return s*fh;
}
void dfs1(int u)
{
int i,j,v;
vis[u]=true;
for(j=1;(1<<j)<=n;j++)
{
P[u][j]=P[P[u][j-1]][j-1];
mx[u][j]=max(mx[u][j-1],mx[P[u][j-1]][j-1]);
mn[u][j]=min(mn[u][j-1],mn[P[u][j-1]][j-1]);
lc[u][j]=max(lc[u][j-1],lc[P[u][j-1]][j-1]);
lc[u][j]=max(lc[u][j],mx[P[u][j-1]][j-1]-mn[u][j-1]);
rc[u][j]=max(rc[u][j-1],rc[P[u][j-1]][j-1]);
rc[u][j]=max(rc[u][j],mx[u][j-1]-mn[P[u][j-1]][j-1]);
}
for(i=Head[u];i!=-1;i=edge[i].next)
{
v=edge[i].end;
if(vis[v]==false)
{
deep[v]=deep[u]+1;
P[v][0]=u;
mx[v][0]=max(a[u],a[v]);//最大值
mn[v][0]=min(a[u],a[v]);//最小值
lc[v][0]=max(0,a[u]-a[v]);//从i点到达fa[i][j]点的最大利润.
rc[v][0]=max(0,a[v]-a[u]);//从fa[i][j]点到达i点的最大利润.
dfs1(v);
}
}
}
/*void Ycl()
{
int i,j;
for(j=1;(1<<j)<=n;j++)
{
for(i=1;i<=n;i++)
{
if(P[i][j-1]!=-1)
{
P[i][j]=P[P[i][j-1]][j-1];
mx[i][j]=max(mx[i][j],max(mx[i][j-1],mx[P[i][j-1]][j-1]));
mn[i][j]=min(mn[i][j],min(mn[i][j-1],mn[P[i][j-1]][j-1]));
lc[i][j]=max(lc[i][j],max(lc[i][j-1],lc[P[i][j-1]][j-1]));
lc[i][j]=max(lc[i][j],mx[P[i][j-1]][j-1]-mn[i][j-1]);
rc[i][j]=max(rc[i][j],max(rc[i][j-1],rc[P[i][j-1]][j-1]));
rc[i][j]=max(rc[i][j],mx[i][j-1]-mn[P[i][j-1]][j-1]);
}
}
}
}*/
int LCA(int x,int y)
{
int i,j;
if(deep[x]<deep[y])swap(x,y);
for(i=0;(1<<i)<=deep[x];i++);i--;
for(j=i;j>=0;j--)if(deep[x]-(1<<j)>=deep[y])x=P[x][j];
if(x==y)return x;
for(j=i;j>=0;j--)
{
if(P[x][j]!=-1&&P[x][j]!=P[y][j])
{
x=P[x][j];
y=P[y][j];
}
}
return P[x][0];
}
int MAX1(int x,int y)
{
int i,j,maxv=-INF;
if(deep[x]<deep[y])swap(x,y);
for(i=0;(1<<i)<=deep[x];i++);i--;
for(j=i;j>=0;j--)
{
if(deep[x]-(1<<j)>=deep[y])
{
maxv=max(maxv,lc[x][j]);
x=P[x][j];
}
}
return maxv;
}
int MAX2(int x,int y)
{
int i,j,maxv=-INF;
if(deep[x]<deep[y])swap(x,y);
for(i=0;(1<<i)<=deep[x];i++);i--;
for(j=i;j>=0;j--)
{
if(deep[x]-(1<<j)>=deep[y])
{
maxv=max(maxv,rc[x][j]);
x=P[x][j];
}
}
return maxv;
}
int MX(int x,int y)
{
int i,j,maxv=-INF;
if(deep[x]<deep[y])swap(x,y);
for(i=0;(1<<i)<=deep[x];i++);i--;
for(j=i;j>=0;j--)
{
if(deep[x]-(1<<j)>=deep[y])
{
maxv=max(maxv,mx[x][j]);
x=P[x][j];
}
}
return maxv;
}
int MN(int x,int y)
{
int i,j,minv=INF;
if(deep[x]<deep[y])swap(x,y);
for(i=0;(1<<i)<=deep[x];i++);i--;
for(j=i;j>=0;j--)
{
if(deep[x]-(1<<j)>=deep[y])
{
minv=min(minv,mn[x][j]);
x=P[x][j];
}
}
return minv;
}
int Ask(int x,int y)
{
int lca=LCA(x,y),xx=x,yy=y,i,j;
int maxxx=-INF,minnn=INF,ans=0;
if(deep[x]<deep[lca])swap(x,lca);
for(i=0;(1<<i)<=deep[x];i++);i--;
for(j=i;j>=0;j--)
{
if(deep[x]-(1<<j)>=deep[lca])
{
ans=max(ans,max(lc[x][j],mx[x][j]-minnn));
minnn=min(mn[x][j],minnn);
x=P[x][j];
}
}
if(deep[y]<deep[lca])swap(y,lca);
for(i=0;(1<<i)<=deep[y];i++);i--;
for(j=i;j>=0;j--)
{
if(deep[y]-(1<<j)>=deep[lca])
{
ans=max(ans,max(rc[y][j],maxxx-mn[y][j]));
maxxx=max(mx[y][j],maxxx);
y=P[y][j];
}
}
return max(ans,maxxx-minnn);
}
int main()
{
int bb,ee,i,j,m,x,y,ans,lca;
n=read();
for(i=1;i<=n;i++)a[i]=read();
memset(Head,-1,sizeof(Head));cnt=1;
for(i=1;i<n;i++)
{
bb=read();ee=read();
addedge1(bb,ee);
}
memset(P,-1,sizeof(P));
/*for(j=1;(1<<j)<=n;j++)
{
for(i=1;i<=n;i++)
{
mn[i][j]=0;mx[i][j]=0;
lc[i][j]=rc[i][j]=0;
}
}*/
dfs1(1);//Ycl();
m=read();
for(i=1;i<=m;i++)
{
x=read();y=read();
if(x==y)printf("0\n");
else// if(x<y)
{
printf("%d\n",Ask(x,y));
//if(x>y)swap(x,y);
/*lca=LCA(x,y);
ans=0;
ans=max(ans,MAX1(x,lca));
ans=max(ans,MAX2(lca,y));
ans=max(ans,MX(lca,y)-MN(x,lca));
printf("%d\n",ans);*/
}
/*else
{
lca=LCA(x,y);
ans=-INF;
ans=max(ans,MAX1(x,lca));
ans=max(ans,MAX2(y,lca));
ans=max(ans,MX(y,lca)-MN(x,lca));
printf("%d\n",ans);
}*/
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: