其他分享
首页 > 其他分享> > [APIO2014]连珠线 题解

[APIO2014]连珠线 题解

作者:互联网

我们设初始的那个点为root。则所有的蓝色链都是形如\(father-now-son\)。

我们设计两个dp状态: \(dp_{i,0}\)表示i号点不作为蓝色链的中间点,\(dp_{i,1}\)表示作为中间点。则以下的转移就非常容易了。

\(dp_{i,0}=\sum \max(dp_{u,1}+w,dp_{u,0})\)

\(dp_{i,1}=\sum \max (dp_{u,1}+w,dp_{u,0}) + \max\{dp_{u,0}+w - \max (dp_{u,1}+w,dp_{u,0}) \}\)

换根dp就ok了。

#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
const int MAXN=200000+20;
int n,rest=-2e9,dp[MAXN][2];
vector<mp> g[MAXN];
void prework(int now,int pre){
	int Max=-2e9;
	dp[now][0]=0;
	for(auto it:g[now]){
		int u,w; u=it.FIR,w=it.SEC; 
		if(u==pre) continue;
		prework(u,now);
		dp[now][0]+=max(dp[u][1]+w,dp[u][0]);
		check_max(Max,dp[u][0]+w-max(dp[u][1]+w,dp[u][0]));
	}
	dp[now][1]=Max+dp[now][0];
}
void change_root(int now,int pre){
	vector<mp> V;
	V.PB({-2e9,-1});
	dp[now][0]=0;
	for(auto it:g[now]){
		int u,w; u=it.FIR,w=it.SEC;
		dp[now][0]+=max(dp[u][1]+w,dp[u][0]);
		V.PB({dp[u][0]+w-max(dp[u][1]+w,dp[u][0]),u});
	}
	check_max(rest,dp[now][0]);
	sort(ALL(V)),reverse(ALL(V));
	int old=dp[now][0];
	for(auto it:g[now]){
		int u=it.FIR,w=it.SEC;
		if(u!=pre){
			dp[now][0]=old-max(dp[u][1]+w,dp[u][0]);
			dp[now][1]=dp[now][0]+(V[0].SEC==u? V[1].FIR:V[0].FIR);
			change_root(u,now);
		}
	}
}
int main(){
	scanf("%d",&n);
	rb(i,2,n){
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		g[a].PB({b,c});
		g[b].PB({a,c});
	}
	prework(1,0);
	change_root(1,0);
	cout<<rest<<endl;
	return 0;
}

标签:FIR,int,题解,APIO2014,max,连珠,now,dp,define
来源: https://www.cnblogs.com/gary-2005/p/14059726.html