POJ 3728 The merchant 离线tarjan
来源:互联网 发布:古筝软件下载手机 编辑:程序博客网 时间:2024/06/06 03:37
题目链接
http://poj.org/problem?id=3728
题意
一件商品在每个城市的价格都不一样,某个商人决定利用这个来赚钱,他想知道从某个起点到某终点,可以获得的最大利润。总共q次询问。
思路
对于询问中的u和v,lca为u和v的最近公共祖先
up[u] 表示从u往lca方向走能获得的最大利润
down[u]表示从lca方向往u走能获得的最大利润
Max[u] 表示从u到lca这段路径中的最大值
Min[u] 表示从u到lca这段路径中的最小值
这些值的更新是在找祖先的过程中更新
#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<vector>#include<string>#include<queue>#include<stack>#include<set>#include<map>#define ll long longusing namespace std;const int INF = ( 2e9 ) + 2;const ll maxn = 5e4+10;struct edge{ int u,v,next;}e[2*maxn],que[2*maxn],l[2*maxn];int head1[maxn],head2[maxn],head3[maxn];int tot1,tot2,tot3;int ans[maxn];int Max[maxn],Min[maxn],up[maxn],down[maxn],f[maxn];bool vis[maxn];void init(){ memset(head1,-1,sizeof(head1)); memset(head2,-1,sizeof(head2)); memset(head3,-1,sizeof(head3)); tot1=tot2=tot3=0;}void add_edge(int u,int v){ e[tot1].v=v; e[tot1].next=head1[u]; head1[u]=tot1++;}void add_que(int u,int v){ que[tot2].u=u; que[tot2].v=v; que[tot2].next=head2[u]; head2[u]=tot2++;}void add_lca(int u,int v){ l[tot3].v=v; l[tot3].next=head3[u]; head3[u]=tot3++;}int Find(int x){ if(f[x]==x)return x; int p=f[x]; f[x]=Find(f[x]); up[x]=max(up[x],max(up[p],Max[p]-Min[x])); down[x]=max(down[x],max(down[p],Max[x]-Min[p])); Max[x]=max(Max[x],Max[p]); Min[x]=min(Min[x],Min[p]); return f[x];}int input(int n){ int u,v,q; for(int i=1;i<=n;i++) { scanf("%d",&Max[i]); Min[i]=Max[i]; up[i]=down[i]=0; } init(); for(int i=1;i<=n-1;i++) { scanf("%d%d",&u,&v); add_edge(u,v); add_edge(v,u); } scanf("%d",&q); for(int i=1;i<=q;i++) { scanf("%d%d",&u,&v); add_que(u,v); add_que(v,u); } return q;}void tarjan(int u){ f[u]=u; vis[u]=true; int v; for(int i=head2[u];i!=-1;i=que[i].next) { v=que[i].v; if(vis[v]) { int LCA=Find(v); add_lca(LCA,i); } } for(int i=head1[u];i!=-1;i=e[i].next) { v=e[i].v; if(!vis[v]) { tarjan(v); f[v]=u; } } for(int i=head3[u];i!=-1;i=l[i].next) { int id=l[i].v; if((id&1))id=id^1; int u=que[id].u,v=que[id].v; Find(u); Find(v); int t=id/2; // 答案要不是在u->lca 这一段中 要不就在lca->v 中,要不就跨越了lca ans[t]=max(up[u],down[v]); ans[t]=max(ans[t],Max[v]-Min[u]); }}void solve(int q){ memset(vis,0,sizeof(vis)); tarjan(1); for(int i=0;i<q;i++) printf("%d\n",ans[i]);}int main(){ int n;// freopen("in.txt","r",stdin); while(~scanf("%d",&n)) { int q=input(n); solve(q); }}
阅读全文
0 0
- POJ 3728 The merchant 离线tarjan
- poj 3728 The merchant(tarjan求lca)
- POJ 3728 The merchant (Tarjan LCA)
- *POJ 3728 - The merchant(LCA‘ Tarjan)
- Poj 3728The merchant (tarjan-LCA高级应用)
- poj 3728 The merchant(离线LCA 的应用,5级)
- POJ 3728 The merchant
- poj 3728 The merchant
- POJ 3728 The merchant
- POJ-3728-The merchant
- POJ 3728 【The merchant】
- POJ 3728 The merchant
- POJ 3728 The merchant
- poj 3728 The merchant
- POJ 3728 The merchant
- The merchant - POJ 3728 LCA
- POJ 3728:The merchant LCA
- |poj 3728|LCA|The merchant
- SEO 是什么?
- c#——扩展方法
- Linux下应用进程消失原因分析
- Rhyme/LinuxStudyNote7.1.3_用户和用户组管理(1)-用户配置文件(4)-组密码文件/etc/gshadow详细解析
- 【Android】源码分析
- POJ 3728 The merchant 离线tarjan
- 我的技术日志终于开张了
- iOS11 适配那些事1----亲测可行!
- Windows 2008 Server线程池前瞻(原创)
- 机器学习(Machine Learning)- 吴恩达(Andrew Ng )-笔记
- 基于队列的最短路径搜索算法(A*算法)实现
- 基于堆栈的时间复杂度为O(n)的箱子排序算法实现
- 一个愚蠢的错误,一次深刻的教训
- 模板类使用friend时需要注意的一个问题