zoukankan      html  css  js  c++  java
  • CF1083A The Fair Nut and the Best Path

    CF1083A The Fair Nut and the Best Path

    • 先把边权搞成点权(其实也可以不用),那么就是询问树上路径的最大权值.
    • 任意时刻权值非负的限制可以不用管,因为若走路径 (u o v) ,走到 (w) 权值为负数了,那么直接从 (w) 下一个点开始走显然更优.这个限制是多余的.
    • 那么问题就很简单了,经典 (dp) 做法,记 (f(i))(i) 子树内一点到 (i) 所有路径中的最大权值, (O(n)) 即可解决问题.
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define mp make_pair
    #define pii pair<int,int>
    inline int read()
    {
    	int x=0;
    	bool pos=1;
    	char ch=getchar();
    	for(;!isdigit(ch);ch=getchar())
    		if(ch=='-')
    			pos=0;
    	for(;isdigit(ch);ch=getchar())
    		x=x*10+ch-'0';
    	return pos?x:-x;
    }
    const int MAXN=6e5+10;
    int cnt,head[MAXN],to[MAXN<<1],nx[MAXN<<1];
    int w[MAXN];
    inline void addedge(int u,int v)
    {
    	++cnt;
    	to[cnt]=v;
    	nx[cnt]=head[u];
    	head[u]=cnt;
    	swap(u,v);
    	++cnt;
    	to[cnt]=v;
    	nx[cnt]=head[u];
    	head[u]=cnt;
    }
    int n;
    ll f[MAXN];
    ll ans=0;
    void upd(ll x,ll &mx,ll &sc)
    {
    	if(x>=mx)
    		sc=mx,mx=x;
    	else if(x>sc)
    		sc=x;
    }
    void dfs(int u,int fa)
    {
    	ll mx=0,sc=0;
    	for(int i=head[u];i;i=nx[i])
    		{
    			int v=to[i];
    			if(v==fa)
    				continue;
    			dfs(v,u);
    			upd(f[v],mx,sc);
    		}
    	f[u]=mx+w[u];
    	ans=max(mx+sc+w[u],ans);
    }
    int main()
    {
    	n=read();
    	for(int i=1;i<=n;++i)
    		w[i]=read();
    	for(int i=1;i<n;++i)
    		{
    			int u=read(),v=read();
    			addedge(u,i+n);
    			addedge(v,i+n);
    			w[i+n]=-1*read();
    		}
    	dfs(1,0);
    	cout<<ans<<endl;
    	return 0;
    }
    
  • 相关阅读:
    docker的安装
    Linux的常用命令
    HTTP协议,HTTPS协议,Websocket协议
    常用排序
    go的数组,切片,map
    if-else,switch,for循环
    go的函数,包以及mode的补充
    Android学习笔记——从源码看Handler的处理机制
    ElementUI
    关于IO的理解
  • 原文地址:https://www.cnblogs.com/jklover/p/10418077.html
Copyright © 2011-2022 走看看