P2986 Great Cow Gathering G

Posted towboa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2986 Great Cow Gathering G相关的知识,希望对你有一定的参考价值。

 

换根dp, father -> son  , 基本是加减

 

#include <bits/stdc++.h>
using namespace std ;
 const int N=1e5+2,M=N*5;
 #define int long long
 int n,a[N],sz[N],g[N],f[N],S;
 int nxt[M],go[M],w[M],hd[N],all;
 
 void add(int x,int y,int z)
 	go[++all]=y,nxt[all]=hd[x],w[all]=z;
	hd[x]=all;
 
 void d0(int x,int fa)
 	int i,y,z;
 	sz[x]=a[x];
 	
	  for(i=hd[x];i;i=nxt[i])
 		 y=go[i],z=w[i]; 
		 if(y!=fa) d0(y,x),sz[x]+=sz[y];
 	  
 	  for(i=hd[x];i;i=nxt[i])
	  	y=go[i],z=w[i];
	  	if(y!=fa) g[x]+=g[y]+sz[y]*z;
	  
 
 
 void dfs(int x,int fa)
 	int i,y,z;
 	
	  for(i=hd[x];i;i=nxt[i])
 		 y=go[i],z=w[i]; 
		 if(y!=fa)
		 	f[y]=f[x]-z*sz[y]+z*(S-sz[y]);
		 	dfs(y,x);
		 
 	  
 
 signed main()
 	int i,x,y,z,t=1e9;
 	cin>>n;
 	for(i=1;i<=n;i++) cin>>a[i],S+=a[i];
 	for(i=1;i<n;i++) cin>>x>>y>>z,add(x,y,z),add(y,x,z);
 	d0(1,0);
    dfs(1,0);
 	
 	for(i=1;i<=n;i++) t=min(t,f[i]);
 	
 	cout<<t+g[1]<<\'\\n\';
 
 
 

 

[USACO10MAR]Great Cow Gathering G(换根dp)

[USACO10MAR]Great Cow Gathering G

换根dp模板题。

同时记录(sz[u])代表(u)的子树内有多少奶牛,那转移时即为(dp[u]=dp[v]+sz[v] imes val(u,v))

注意开long long。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100010;
const ll inf = 0x7f7f7f7f7f7f7f7f;
template <typename T> void read(T &x) {
	T f = 1;
	char ch = getchar();
	for (; !isdigit(ch); ch = getchar()) if (ch == ‘-‘) f = -1;
	for (x = 0; isdigit(ch); ch = getchar()) x = x * 10 + ch - ‘0‘;
	x *= f;
}
template <typename T> void cmin(T &x, T y) {if (y < x) x = y;}
struct node{
	int pre, to;
	ll val;
}edge[N << 1];
int head[N], tot;
int n;
int c[N];
ll dp[N], sz[N];
ll ans = inf;
void add(int u, int v, int l) {
	edge[++tot] = node{head[u], v, l};
	head[u] = tot;
}
void dfs1(int x, int fa) {
	sz[x] = c[x];
	for (int i = head[x]; i; i = edge[i].pre) {
		int y = edge[i].to;
		if (y == fa) continue;
		dfs1(y, x);
		sz[x] += sz[y];
		dp[x] += dp[y] + sz[y] * edge[i].val;
	}
}
void cut(int x, int y, int val) {
	dp[x] -= dp[y] + sz[y] * val;
	sz[x] -= sz[y];
}
void link(int x, int y, int val) {
	dp[x] += dp[y] + sz[y] * val;
	sz[x] += sz[y];
}
void change_root(int x, int y, int val) {
	cut(x, y, val);
	link(y, x, val);
}
void dfs2(int x, int fa) {
	cmin(ans, dp[x]);
	for (int i = head[x]; i; i = edge[i].pre) {
		int y = edge[i].to;
		if (y == fa) continue;
		change_root(x, y, edge[i].val);
		dfs2(y, x);
		change_root(y, x, edge[i].val);
	}
}
int main() {
	read(n);
	for (int i = 1; i <= n; i++) read(c[i]);
	for (int i = 1, a, b, v; i < n; i++) {
		read(a); read(b); read(v);
		add(a, b, v);
		add(b, a, v);
	}
	dfs1(1, 0);
	dfs2(1, 0);
	printf("%lld", ans);
	return 0;
}

以上是关于P2986 Great Cow Gathering G的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 P2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat…

P2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat…

P2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat…

P2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat…

[USACO10MAR]Great Cow Gathering G(换根dp)

P5157 [USACO18DEC]The Cow Gathering