zoukankan      html  css  js  c++  java
  • HDU 5052 LCT

    Yaoge’s maximum profit

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 516    Accepted Submission(s): 150


    Problem Description
    Yaoge likes to eat chicken chops late at night. Yaoge has eaten too many chicken chops, so that Yaoge knows the pattern in the world of chicken chops. There are N cities in the world numbered from 1 to N . There are some roads between some cities, and there is one and only one simple path between each pair of cities, i.e. the cities are connected like a tree. When Yaoge moves along a path, Yaoge can choose one city to buy ONE chicken chop and sell it in a city after the city Yaoge buy it. So Yaoge can get profit if Yaoge sell the chicken chop with higher price. Yaoge is famous in the world. AFTER Yaoge has completed one travel, the price of the chicken chop in each city on that travel path will be increased by V .
     

    Input
    The first line contains an integer T (0 < T ≤ 10), the number of test cases you need to solve. For each test case, the first line contains an integer N (0 < N ≤ 50000), the number of cities. For each of the next N lines, the i-th line contains an integer Wi(0 < Wi ≤ 10000), the price of the chicken chop in city i. Each of the next N - 1 lines contains two integers X Y (1 ≤ X, Y ≤ N ), describing a road between city X and city Y . The next line contains an integer Q(0 ≤ Q ≤ 50000), the number of queries. Each of the next Q lines contains three integer X Y V(1 ≤ X, Y ≤ N ; 0 < V ≤ 10000), meaning that Yaoge moves along the path from city X to city Y , and the price of the chicken chop in each city on the path will be increased by V AFTER Yaoge has completed this travel.
     

    Output
    For each query, output the maximum profit Yaoge can get. If no positive profit can be earned, output 0 instead.
     

    Sample Input
    1 5 1 2 3 4 5 1 2 2 3 3 4 4 5 5 1 5 1 5 1 1 1 1 2 5 1 1 1 2 1
     

    Sample Output
    4 0 0 1 0
     

    Source
     


    路径大值与小值差值的最大值,当中满足小值在大值前面出现,添�求u->:v的路径上答案,能够先u->make_root(),然后v->access(),然后输出答案就能够了。

    代码:

    /* ***********************************************
    Author :rabbit
    Created Time :2014/11/2 19:01:37
    File Name :4.cpp
    ************************************************ */
    #pragma comment(linker, "/STACK:102400000,102400000")
    #include <stdio.h>
    #include <iostream>
    #include <algorithm>
    #include <sstream>
    #include <stdlib.h>
    #include <string.h>
    #include <limits.h>
    #include <string>
    #include <time.h>
    #include <math.h>
    #include <queue>
    #include <stack>
    #include <set>
    #include <map>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define eps 1e-8
    #define pi acos(-1.0)
    typedef long long ll;
    const int maxn=100100;
    struct Node *null;
    struct Node{
    	Node *ch[2],*fa;
    	int Max,Min,mm,rmm,rev,add,val;
    	inline void clear(int _val){
    		fa=ch[0]=ch[1]=null;
    		Max=Min=val=_val;
    		rev=add=mm=rmm=0;
    	}
    	inline void push_up(){
    		if(this==null)return;
    		mm=0;
    		mm=max(mm,ch[0]->mm);
    		mm=max(mm,ch[1]->mm);
    		mm=max(mm,max(val,ch[1]->Max)-ch[0]->Min);
    		mm=max(mm,ch[1]->Max-min(val,ch[0]->Min));
    		rmm=0;
    		rmm=max(rmm,ch[0]->rmm);
    		rmm=max(rmm,ch[1]->rmm);
    		rmm=max(rmm,max(val,ch[0]->Max)-ch[1]->Min);
    		rmm=max(rmm,ch[0]->Max-min(val,ch[1]->Min));
    		Max=max(val,max(ch[0]->Max,ch[1]->Max));
    		Min=min(val,min(ch[0]->Min,ch[1]->Min));
    	}
    	inline void setc(Node *p,int d){
    		ch[d]=p;
    		p->fa=this;
    	}
    	inline bool d(){
    		return fa->ch[1]==this;
    	}
    	inline bool isroot(){
    		return fa==null||fa->ch[0]!=this&&fa->ch[1]!=this;
    	}
    	inline void flip(){
    		if(this==null)return;
    		swap(ch[0],ch[1]);
    		rev^=1;
    		swap(mm,rmm);
    	}
    	inline void update_add(int w){
    		if(this==null)return;
    		Max+=w;
    		Min+=w;
    		val+=w;
    		add+=w;
    	}
    	inline void push_down(){
    		if(add){
    			ch[0]->update_add(add);
    			ch[1]->update_add(add);
    			add=0;
    		}
    		if(rev){
    			ch[0]->flip();
    			ch[1]->flip();
    			rev=0;
    		}
    	}
        inline void go(){
    		if(!isroot())fa->go();
    		push_down();
    	}
    	inline void rot(){
    		Node *f=fa,*ff=fa->fa;
    		int c=d(),cc=fa->d();
    		f->setc(ch[!c],c);
    		this->setc(f,!c);
    		if(ff->ch[cc]==f)ff->setc(this,cc);
    		else  this->fa=ff;
    		f->push_up();
    	}
    	inline Node *splay(){
    		go();
    		while(!isroot()){
    			if(!fa->isroot())
    				d()==fa->d()?fa->rot():rot();
    			rot();
    		}
    		push_up();
    		return this;
    	}
    	inline Node *access(){
    		for(Node *p=this,*q=null;p!=null;q=p,p=p->fa){
    			p->splay()->setc(q,1);
    			p->push_up();
    		}
    		return splay();
    	}
    	inline Node *find_root(){
    		Node *x;
    		for(x=access();x->push_down(),x->ch[0]!=null;x=x->ch[0]);
    		return x;
    	}
    	void make_root(){
    		access()->flip();
    	}
    };
    Node pool[maxn],*tail;
    Node*node[maxn];
    struct Edge{
    	int next,to;
    }edge[maxn*2];
    int head[maxn],tol;
    inline void addedge(int u,int v){
    	edge[tol].to=v;
    	edge[tol].next=head[u];
    	head[u]=tol++;
    }
    void dfs(int u,int pre){
    	for(int i=head[u];i!=-1;i=edge[i].next){
    		int v=edge[i].to;
    		if(v==pre)continue;
    		node[v]->fa=node[u];
    		dfs(v,u);
    	}
    }
    int main()
    {
         //freopen("data.in","r",stdin);
         //freopen("data.out","w",stdout);
         int n,m,T;
    	 scanf("%d",&T);
    	 while(T--){
    		 scanf("%d",&n);
    		 tail=pool;
    		 null=tail++;
    		 null->val=null->mm=null->rmm=0;
    		 null->Max=-INF;null->Min=INF;
    		 null->ch[0]=null->ch[1]=null->fa=null;
    		 null->add=null->rev=0;
    		 for(int i=1;i<=n;i++){
    			 int w;
    			 scanf("%d",&w);
    			 node[i]=tail++;
    			 node[i]->clear(w);
    		 }
    		 memset(head,-1,sizeof(head));tol=0;
    		 for(int i=1;i<n;i++){
    			 int u,v;
    			 scanf("%d%d",&u,&v);
    			 addedge(u,v);
    			 addedge(v,u);
    		 }
    		 dfs(1,1);
    		 scanf("%d",&m);
    		 while(m--){
    			 int u,v,d;
    			 scanf("%d%d%d",&u,&v,&d);
    			 node[u]->make_root();
    			 node[v]->access();
    			 printf("%d
    ",node[v]->mm);
    			 node[v]->update_add(d);
    		 }
    	 }
         return 0;
    }
    


  • 相关阅读:
    增强型window.showModalDialog弹出模态窗口数据传递高度封装实验 西安
    谈谈Asp.net网站优化二:关于 服务器控件 和 客户端控件(html标签)的选择 西安
    谈谈Asp.net网站优化一:SqlDataReader和DataSet的选择 西安
    我2年来整理的.NET开发类库源代码共享 西安
    类似baidu google分页器效果的代码(修改于 kwklover 同学基础上) 西安
    C#.NET动手开发域名抢注前检测工具。 西安
    解决vs2008 项目文件(b/s)右键“在浏览器中打开”出现两个浏览器 西安
    基于Json的Ajax无刷新分页效果实现(一) 西安
    基于Json的Ajax无刷新分页效果实现(二) 西安
    循环冗余检验 (CRC) 算法原理
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/4082199.html
Copyright © 2011-2022 走看看