您的位置:首页 > 其它

poj3728

2015-10-04 21:27 525 查看
u->v最优解=极大卖出-极小买入,记最近公共祖先r,穷举三种情况:u->v最优解=u->r最优解u->v最优解=r->v最优解u->v最优解=r->v极大卖出-u->r极小买入
</pre><pre name="code" class="cpp">#include<iostream>#include <string>#include<vector>#include<algorithm>#include<set>#include<cmath>using namespace std;#define lch(i) ((i)<<1)#define rch(i) ((i)<<1|1)#define sqr(i) ((i)*(i))#define pii pair<int,int>#define mp make_pair#define FOR(i,b,e) for(int i=b;i<=e;i++)#define ms(a)	memset(a,0,sizeof(a))const int maxnum = 50005;struct node{int v,next;}edge[maxnum*2];struct node1{int v,nth,next,dir;}qedge[maxnum*2];int p[maxnum],max1[maxnum],min1[maxnum],r2rt[maxnum],rt2r[maxnum],pre[maxnum];int head[maxnum],query[maxnum],vis[maxnum];int ans[maxnum];int ca[maxnum];int find1(int i){if(p[i]==i){return p[i];}int tmp = p[i];p[i]=find1(p[i]);r2rt[i]=max(max(r2rt[i],r2rt[tmp]),max1[i]-min1[tmp]);rt2r[i]=max(max(rt2r[i],rt2r[tmp]),max1[tmp]-min1[i]);max1[i]=max(max1[tmp],max1[i]);min1[i]=min(min1[tmp],min1[i]);return p[i];}void uniontree(int rx,int ry){p[ry]=rx;}void dfs(int rt){p[rt]=rt;for(int i=head[rt];i!=-1;i=edge[i].next){if(edge[i].v==pre[rt])continue;pre[edge[i].v]=rt;dfs(edge[i].v);uniontree(rt,find1(edge[i].v));}vis[rt]=1;for(int i=query[rt];i!=-1;i=qedge[i].next){if(!vis[qedge[i].v])continue;int ca = find1(qedge[i].v);if(qedge[i].dir==0){int rtr=0,mi=min1[rt],pi=rt;while(pi!=ca){rtr=max(max(rtr,max1[pre[pi]]-max1[pi]),max1[pre[pi]]-mi);mi = min(mi,min1[pre[pi]]);pi=pre[pi];}ans[qedge[i].nth]=max(max(rtr,r2rt[qedge[i].v]),max1[qedge[i].v]-mi);}else{int rrt=0,ma=max1[rt],pi=rt;while(pi!=ca){rrt=max(max(rrt,max1[pi]-max1[pre[pi]]),ma-min1[pre[pi]]);ma = max(ma,max1[pre[pi]]);pi=pre[pi];}ans[qedge[i].nth]=max(max(rrt,rt2r[qedge[i].v]),ma-min1[qedge[i].v]);}}}int e=0;void add(int u,int v){edge[e].v=v;edge[e].next=head[u];head[u]=e++;}int f=0;void addq(int u,int v,int i,int dir){qedge[f].v=v;qedge[f].next=query[u];qedge[f].nth=i;qedge[f].dir=dir;query[u]=f++;}int main(){int n,q,u,v;scanf("%d",&n);FOR(i,1,n){scanf("%d",&max1[i]);min1[i]=max1[i];r2rt[i]=rt2r[i]=0;head[i]=-1;query[i]=-1;vis[i]=0;}FOR(i,1,n-1){scanf("%d%d",&u,&v);add(u,v);add(v,u);}scanf("%d",&q);FOR(i,1,q){scanf("%d%d",&u,&v);addq(u,v,i,0);addq(v,u,i,1);}ms(p);pre[1]=0;dfs(1);FOR(i,1,q){printf("%d\n",ans[i]);}return 0;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  lca 并查集