【算法学习】学换根dp有感

自从钻研这换根DP,犹如梁山好汉破了难关。初时只觉这树状结构,分枝繁复,变化多端,哪知竟有此等妙计。每换一根,便能高效算出新解,岂不似宋江指挥众兄弟,调度得当,事半功倍。更妙的是,这容斥之法,恰如兵法计策,分而治之,避开冗余。学之愈深,愈觉精妙,心中豪气顿生,恨不得与众学者痛饮一场,论此技之神通。

感觉这换根dp真的很有意思,也好理解学习(巧的是学之前还做了类似的题目换根

详细见例题洛谷 P3478 [POI2008] STA-Station

换根dp 其实就是容斥和树形dp的结合。

感觉非常之妙。

学习笔记

学习笔记

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e6+10;
int n;
ll siz[N];
ll val[N];
ll ans[N];
vector<int> v[N];

void dfs(int u,int fa){
	siz[u]=1;
	val[u]=val[fa]+1;
	for(int i=0;i<v[u].size();i++){
		int y=v[u][i];
		if(y==fa){
			continue;
		} 
		dfs(y,u);
		siz[u]+=siz[y];
	}
}

void dfs2(int u,int fa){
	for(int i=0;i<v[u].size();i++){
		int y=v[u][i];
		if(y==fa){
			continue;
		} 
		ans[y]=ans[u]+siz[1]-2*siz[y]; 
		dfs2(y,u);
	}
}

int main(){
	ios::sync_with_stdio(false);
	cin>>n;
	
	for(int i=1;i<n;i++){
		int u,vv;
		cin>>u>>vv;
		v[u].push_back(vv);
		v[vv].push_back(u);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		ans[1]+=val[i];
	}
	dfs2(1,0);
	ll mx=-1,id=1;
	for(int i=1;i<=n;i++){
		if(ans[i]>mx){
			mx=ans[i];
			id=i;
		}
	}
	cout<<id;
	return 0;
}
posted @ 2024-09-20 12:27  sad_lin  阅读(6)  评论(0编辑  收藏  举报