BZOJ 1827: [Usaco2010 Mar]gather 奶牛大集会 树形DP
[Usaco2010 Mar]gather 奶牛大集會
Bessie正在計(jì)劃一年一度的奶牛大集會,來自全國各地的奶牛將來參加這一次集會。當(dāng)然,她會選擇最方便的地點(diǎn)來舉辦這次集會。每個(gè)奶牛居住在 N(1<=N<=100,000) 個(gè)農(nóng)場中的一個(gè),這些農(nóng)場由N-1條道路連接,并且從任意一個(gè)農(nóng)場都能夠到達(dá)另外一個(gè)農(nóng)場。道路i連接農(nóng)場A_i和B_i(1 <= A_i <=N; 1 <= B_i <= N),長度為L_i(1 <= L_i <= 1,000)。集會可以在N個(gè)農(nóng)場中的任意一個(gè)舉行。另外,每個(gè)牛棚中居住者C_i(0 <= C_i <= 1,000)只奶牛。在選擇集會的地點(diǎn)的時(shí)候,Bessie希望最大化方便的程度(也就是最小化不方便程度)。比如選擇第X個(gè)農(nóng)場作為集會地點(diǎn),它的不方便程度是其它牛棚中每只奶牛去參加集會所走的路程之和,(比如,農(nóng)場i到達(dá)農(nóng)場X的距離是20,那么總路程就是C_i*20)。幫助Bessie找出最方便的地點(diǎn)來舉行大集會。 考慮一個(gè)由五個(gè)農(nóng)場組成的國家,分別由長度各異的道路連接起來。在所有農(nóng)場中,3號和4號沒有奶牛居住。?
?
分析:
先以1(隨便)為根dfs一次,求出以每個(gè)節(jié)點(diǎn)為根時(shí),他所在的子樹的人數(shù)個(gè)數(shù)sz,并且計(jì)算出以1為根時(shí)的不方便度。
第二次時(shí),繼續(xù)以1為根,這時(shí)假設(shè)當(dāng)前節(jié)點(diǎn)為x,不方便度為cost,兒子節(jié)點(diǎn)為y。把x的不方便度cost向y轉(zhuǎn)化,其實(shí)就是
cost+(sz[1]-2*sz[y])*edge[i].cost (畫個(gè)圖就知道了。。。)
?
#include <set> #include <map> #include <list> #include <cmath> #include <queue> #include <stack> #include <string> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm>using namespace std;typedef long long ll; typedef unsigned long long ull;#define debug puts("here") #define rep(i,n) for(int i=0;i<n;i++) #define rep1(i,n) for(int i=1;i<=n;i++) #define REP(i,a,b) for(int i=a;i<=b;i++) #define foreach(i,vec) for(unsigned i=0;i<vec.size();i++) #define pb push_back #define RD(n) scanf("%d",&n) #define RD2(x,y) scanf("%d%d",&x,&y) #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w) #define All(vec) vec.begin(),vec.end() #define MP make_pair #define PII pair<int,int> #define PQ priority_queue #define cmax(x,y) x = max(x,y) #define cmin(x,y) x = min(x,y) #define Clear(x) memset(x,0,sizeof(x)) /*#pragma comment(linker, "/STACK:1024000000,1024000000")int size = 256 << 20; // 256MB char *p = (char*)malloc(size) + size; __asm__("movl %0, %%esp\n" :: "r"(p) );*//******** program ********************/const int MAXN = 1e5+5; const ll INF = 1e15;struct Edge{int y,cost,next; }edge[MAXN<<1];int c[MAXN],n; ll dp[MAXN],sz[MAXN],ans[MAXN]; int po[MAXN],tol;inline void add(int x,int y,int cost){edge[++tol].y = y;edge[tol].cost = cost;edge[tol].next = po[x];po[x] = tol; }void dfsDp(int x,int fa){dp[x] = 0;sz[x] = c[x];for(int i=po[x];i;i=edge[i].next){int y = edge[i].y;if(y==fa)continue;dfsDp(y,x);sz[x] += sz[y];dp[x] += sz[y]*edge[i].cost+dp[y];} }void dfsAns(int x,int fa,ll cost){ans[x] = cost;for(int i=po[x];i;i=edge[i].next){int y = edge[i].y;if(y==fa)continue;ll tmp = cost+(sz[1]-2*sz[y])*edge[i].cost;dfsAns(y,x,tmp);} }int main(){#ifndef ONLINE_JUDGEfreopen("sum.in","r",stdin);//freopen("sum.out","w",stdout); #endifwhile(~RD(n)){rep1(i,n)RD(c[i]);int x,y,cost;REP(i,2,n){RD3(x,y,cost);add(x,y,cost);add(y,x,cost);}dfsDp(1,0);dfsAns(1,0,dp[1]);ll tmp = INF;rep1(i,n)cmin(tmp,ans[i]);cout<<tmp<<endl;}return 0; }
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/yejinru/p/3295971.html
總結(jié)
以上是生活随笔為你收集整理的BZOJ 1827: [Usaco2010 Mar]gather 奶牛大集会 树形DP的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 树状数组(Binary Indexed
- 下一篇: HDOJ树形DP专题之Centroid