POJ
来源:互联网 发布:bose qc35淘宝假货 编辑:程序博客网 时间:2024/06/07 02:17
POJ - 3728传送
题意:给定n个城市,每两个城市之间有且仅有一条路。货物在各个城市的价格不同,在一条路径中,
思路:利用LCA倍增法求解过程,同时求出最大利润。
在LCA倍增法中,设fa[x][i]表示,x点的2^i的祖宗节点。
同理设up[x][i]为从x走到fa[x][i]过程能获得的最大利益
设down[x][i]为从fa[x][i]走到x过程的最大利益
设fma[x][i]为x和fa[x][i]之间的最大价格
设fmi[x][i]为x和fa[x][i]之间的最小价格
在倍增法过程就能快速求解出最大利益
注意维护过程
#include<cstring>#include<iostream>#include<cstdio>#include<vector>using namespace std;#define fma fmaxxxxconst int INF=0x3f3f3f3f;const int N=50500;int dep[N],fa[N][20],fma[N][20],fmi[N][20],up[N][20],down[N][20],val[N];int n,m;vector<int>g[N];void dfs(int x,int pa,int d){ dep[x]=d; for(int i=0;i<g[x].size();i++) { int y=g[x][i]; if(y==pa)continue; fa[y][0]=x; fma[y][0]=max(val[x],val[y]); fmi[y][0]=min(val[x],val[y]); up[y][0]=max(0,val[x]-val[y]); down[y][0]=max(0,val[y]-val[x]); dfs(y,x,d+1); }}void init(){ for(int j=1;j<=m;j++) { for(int i=1;i<=n;i++) { if(fa[i][j-1]<0){fa[i][j-1]=-1;continue;} fa[i][j]=fa[fa[i][j-1]][j-1]; fma[i][j]=max(fma[i][j-1],fma[fa[i][j-1]][j-1]); fmi[i][j]=min(fmi[i][j-1],fmi[fa[i][j-1]][j-1]); up[i][j]=max(up[i][j-1],up[fa[i][j-1]][j-1]); up[i][j]=max(up[i][j],fma[fa[i][j-1]][j-1]-fmi[i][j-1]); down[i][j]=max(down[i][j-1],down[fa[i][j-1]][j-1]); down[i][j]=max(down[i][j],fma[i][j-1]-fmi[fa[i][j-1]][j-1]); } }}int LCA(int x,int y){ int ans=0,mixx=val[x],maxx=val[y]; if(dep[x]>dep[y]) { for(int i=0;i<=m;i++) { if((dep[x]-dep[y])&(1<<i)) { ans=max(ans,up[x][i]); ans=max(ans,fma[x][i]-mixx); mixx=min(mixx,fmi[x][i]); x=fa[x][i]; } } } else { for(int i=0;i<=m;i++) { if((dep[y]-dep[x])&(1<<i)) { ans=max(ans,down[y][i]); ans=max(ans,maxx-fmi[y][i]); maxx=max(maxx,fma[y][i]); y=fa[y][i]; } } } if(x==y) { ; } else { for(int i=m;i>=0;i--) { if(fa[x][i]!=fa[y][i]) { ans=max(ans,up[x][i]); ans=max(ans,fma[x][i]-mixx); mixx=min(mixx,fmi[x][i]); ans=max(ans,down[y][i]); ans=max(ans,maxx-fmi[y][i]); maxx=max(maxx,fma[y][i]); x=fa[x][i]; y=fa[y][i]; } } mixx=min(mixx,fmi[x][0]); maxx=max(maxx,fma[y][0]); } ans=max(ans,maxx-mixx); printf("%d\n",ans); return fa[x][0];}int main(){ int x,y; while(scanf("%d",&n)!=EOF) { m=0; for(int i=1;i<=n;i++) g[i].clear(); while(n>=(1<<m))m++; for(int i=1;i<=n;i++) scanf("%d",&val[i]); for(int i=1;i<n;i++) { scanf("%d%d",&x,&y); g[x].push_back(y); g[y].push_back(x); } fa[1][0]=-1; dfs(1,-1,1); init(); int TAT; scanf("%d",&TAT); while(TAT--) { scanf("%d%d",&x,&y); int ret=LCA(x,y); //-cout<<ret<<" **"<<endl; } } return 0;}
阅读全文
0 0
- POJ
- poj
- POJ
- POJ
- poj
- poj
- POJ
- POJ
- poj
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- solr sort function
- Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)'
- 【超级实用】程序添加后台执行的选项
- JAVA单例模式II 双重检测锁 内部静态类 枚举 学习笔记
- 使用URLConnection发送GET和POST请求
- POJ
- 屏幕录像专家破解版2016
- QT学习——QT5.9.1集成至VS2015
- Retrofit源码分析 (三.Proxy代理)
- python学习——list
- SET ANSI_NULLS ON
- Tomcat集群解决方案(MARK)
- linux 常用系统变量
- sctp 编程接口指南