【洛谷2986】【USACO10MAR】伟大的奶牛聚集
題面
題目描述
Bessie is planning the annual Great Cow Gathering for cows all across the country and, of course, she would like to choose the most convenient location for the gathering to take place.
Each cow lives in one of N (1 <= N <= 100,000) different barns (conveniently numbered 1..N) which are connected by N-1 roads in such a way that it is possible to get from any barn to any other barn via the roads. Road i connects barns A_i and B_i (1 <= A_i <= N; 1 <= B_i <= N) and has length L_i (1 <= L_i <= 1,000). The Great Cow Gathering can be held at any one of these N barns. Moreover, barn i has C_i (0 <= C_i <= 1,000) cows living in it.
When choosing the barn in which to hold the Cow Gathering, Bessie wishes to maximize the convenience (which is to say minimize the inconvenience) of the chosen location. The inconvenience of choosing barn X for the gathering is the sum of the distances all of the cows need to travel to reach barn X (i.e., if the distance from barn i to barn X is 20, then the travel distance is C_i*20). Help Bessie choose the most convenient location for the Great Cow
Gathering.
Consider a country with five barns with [various capacities] connected by various roads of varying lengths. In this set of barns, neither barn 3 nor barn 4 houses any cows.
1 3 4 5
@--1--@--3--@--3--@[2]
[1] |
2 | @[1] 2 Bessie can hold the Gathering in any of five barns; here is the table of inconveniences calculated for each possible location:
Gather ----- Inconvenience ------
Location B1 B2 B3 B4 B5 Total
1 0 3 0 0 14 17
2 3 0 0 0 16 19
3 1 2 0 0 12 15
4 4 5 0 0 6 15
5 7 8 0 0 0 15
If Bessie holds the gathering in barn 1, then the inconveniences from each barn are:
Barn 1 0 -- no travel time there!
Barn 2 3 -- total travel distance is 2+1=3 x 1 cow = 3 Barn 3 0 -- no cows there!
Barn 4 0 -- no cows there!
Barn 5 14 -- total travel distance is 3+3+1=7 x 2 cows = 14 So the total inconvenience is 17.
The best possible convenience is 15, achievable at by holding the Gathering at barns 3, 4, or 5.
Bessie正在計劃一年一度的奶牛大集會,來自全國各地的奶牛將來參加這一次集會。當然,她會選擇最方便的地點來舉辦這次集會。
每個奶牛居住在 N(1<=N<=100,000) 個農場中的一個,這些農場由N-1條道路連接,并且從任意一個農場都能夠到達另外一個農場。道路i連接農場A_i和B_i(1 <= A_i <=N; 1 <= B_i <= N),長度為L_i(1 <= L_i <= 1,000)。集會可以在N個農場中的任意一個舉行。另外,每個牛棚中居住者C_i(0 <= C_i <= 1,000)只奶牛。
在選擇集會的地點的時候,Bessie希望最大化方便的程度(也就是最小化不方便程度)。比如選擇第X個農場作為集會地點,它的不方便程度是其它牛棚中每只奶牛去參加集會所走的路程之和,(比如,農場i到達農場X的距離是20,那么總路程就是C_i*20)。幫助Bessie找出最方便的地點來舉行大集會。
輸入格式:
Line 1: A single integer: N
Lines 2..N+1: Line i+1 contains a single integer: C_i
Lines N+2..2*N: Line i+N+1 contains three integers: A_i, B_i, and L_i
輸出格式:
Line 1: The minimum inconvenience possible
輸入樣例#1:
5
1
1
0
0
2
1 3 1
2 3 2
3 4 3
4 5 3
輸出樣例#1:
15
題解
考慮如果依次枚舉每一個點作為集會的地點
使用DFS進行計算
然后再依次比較
時間復雜度O(n^2)
但是n的范圍太大,顯然會超時。
那么,我們應當如何優化?
先看看樣例
通過一次O(n)的計算,很容易得出來
如果選擇1號節點,答案就是17
既然O(n^2)的計算無法在時間內求解
那么是否可以遞推出來呢?
顯然是可以的。
觀察如果已經知道1號節點所需的時間
那么,我們可以做如下假設:
① 所有的牛首先到達了1號節點
② 3號節點以及他子樹上的節點都需要退回1->3的路徑的長度
③ 除了3號節點以及他子樹上的節點都需要前進1->3的路徑的長度
通過上面的三條東西,我們就可以從任意一個父節點推出子節點的時間
所以,又是一遍O(n)的計算就可以推出最終的答案
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> using namespace std; #define MAX 200100 #define ll long long inline ll read() {register ll x=0,t=1;register char ch=getchar();while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();if(ch=='-'){t=-1;ch=getchar();}while(ch<='9'&&ch>='0'){x=x*10+ch-48;ch=getchar();}return x*t; }ll dis[MAX],C[MAX],Q[MAX],f[MAX],Sum,Ans=1000000000000000000;struct Line {ll v,next,w; }e[MAX];ll h[MAX],cnt=1,N;inline void Add(ll u,ll v,ll w) {e[cnt]=(Line){v,h[u],w};h[u]=cnt++; } //使用兩遍DFS //第一遍以任意點為根節點計算一遍 //dis[i]表示以i為根的子樹到根的距離之和 ll DFS(ll u,ll ff) {ll tot=0;for(ll i=h[u];i;i=e[i].next){ll v=e[i].v;if(v!=ff){ll s=DFS(v,u);//子樹上牛的數量 dis[u]+=dis[v]+e[i].w*s;//統計 tot+=s;//牛的個數}}return Q[u]=tot+C[u]; } //第二遍計算偏移后的值 //先可以假設走到當前節點的父節點 //再讓當前自己點所有牛退回來,父節點的所有牛走過去即可 void DFS2(ll u,ll ff) {for(ll i=h[u];i;i=e[i].next){ll v=e[i].v;if(v!=ff){ll ss=e[i].w;f[v]=f[u]-Q[v]*ss+(Sum-Q[v])*ss;DFS2(v,u);}} }int main() {N=read();for(ll i=1;i<=N;++i)C[i]=read();for(ll i=1;i<=N;++i)Sum+=C[i];//統計牛的總數 for(ll i=1;i<N;++i){ll u=read(),v=read(),w=read();Add(u,v,w);Add(v,u,w);}DFS(1,1);//求出以1為聚集處的結果 DFS2(1,1);//求出其他的偏移值for(ll i=1;i<=N;++i)Ans=min(Ans,f[i]);cout<<Ans+dis[1]<<endl;return 0; }轉載于:https://www.cnblogs.com/cjyyb/p/7215377.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的【洛谷2986】【USACO10MAR】伟大的奶牛聚集的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常见的java开源组件_java开源框架
- 下一篇: 免费生成https证书以及配置