1. 程式人生 > >[補檔][Poi2014]FarmCraft

[補檔][Poi2014]FarmCraft

翻譯 height 輸出 就會 har pen ring lin for

[Poi2014]FarmCraft

題目

mhy住在一棵有n個點的樹的1號結點上,每個結點上都有一個妹子。 mhy從自己家出發,去給每一個妹子都送一臺電腦,每個妹子拿到電腦後就會開始安裝zhx牌殺毒軟件,第i個妹子安裝時間為Ci。 樹上的每條邊mhy能且僅能走兩次,每次耗費1單位時間。mhy送完所有電腦後會回自己家裏然後開始裝zhx牌殺毒軟件。 卸貨和裝電腦是不需要時間的。 求所有妹子和mhy都裝好zhx牌殺毒軟件的最短時間。

INPUT

第一行輸入一個整數N,表示有N個結點 第二行有N個整數C1,C2...Cn,Ci表示第i個妹子安裝殺毒軟件的時間 接下來的N-1行,每行兩個整數x,y,表示x與y之間有一條無向邊

OUTPUT

輸出文件僅包含一行,一個整數表示讓所有妹子和mhy裝好殺毒軟件的最短時間

SAMPLE

INPUT

6 1 8 9 6 3 2 1 3 2 3 3 4 4 5 4 6

OUTPUT

11

解題報告

翻譯真累= =,原題英文版,結果發現翻譯跟英文啥關系沒有,就粘了翻譯,然後發現輸入格式跟輸出格式都沒有翻譯,然後= =,然後我就強行翻譯了一發= = 考試時打了個dfs,騙了5分- - 正解: 貪心。 我們分析題幹,發現每條邊只能過兩次,也就是一進一出,那麽我們進了一個點,我們就要遍歷完整個子樹,所以我們只能跑一遍dfs,然後我們發現dfs一遍的時間是一定的,那麽見每個妹子的時間就在這個時間軸上。 我們定義一個數組rest,代表遍歷完這個節店的子樹,以後我們還要為這個節點所費的時間。 1. 除了1節點,見到一個妹子殺一下毒 2. 我們發現答案是Max(rest[1],c[1])+2×(n-1) 3. 我們考慮如何找rest,我們發現,每個節點的最優rest是 子節點的rest,減去其在這個子樹裏又經過的時間
再和 它的c減去遍歷它的時間 取個Max 技術分享
 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<vector>
 6 using namespace std;
 7 inline int read(){
 8     int sum(0);
 9     char ch(getchar());
10     for(;ch<0||ch>9;ch=getchar());
11
for(;ch>=0&&ch<=9;sum=sum*10+(ch^48),ch=getchar()); 12 return sum; 13 } 14 int n; 15 int w[500001]; 16 int fa[500001],t[500001],rest[500001]; 17 inline int my_max(int a,int b){ 18 return a>b?a:b; 19 } 20 inline int my_min(int a,int b){ 21 return a<b?a:b; 22 } 23 vector<int>g[500001]; 24 inline bool cmp(const int &a,const int &b){ 25 return rest[a]>rest[b]; 26 } 27 inline void dfs(int u){ 28 int size(g[u].size()); 29 for(int i=0;i<size;i++){ 30 int e(g[u][i]); 31 if(e!=fa[u]){ 32 t[u]++; 33 fa[e]=u; 34 dfs(e); 35 t[u]++; 36 t[u]+=t[e]; 37 } 38 } 39 if(u!=1) 40 rest[u]=w[u]-t[u]; 41 int tmp(t[u]); 42 sort(g[u].begin(),g[u].end(),cmp); 43 for(int i=0;i<size;i++){ 44 int e(g[u][i]); 45 if(e!=fa[u]){ 46 tmp-=2+t[e]; 47 rest[u]=my_max(rest[u],rest[e]-tmp-1); 48 } 49 } 50 rest[u]=my_max(0,rest[u]); 51 // cout<<u<<‘ ‘<<w[u]<<‘ ‘<<rest[u]<<endl; 52 } 53 int main(){ 54 n=read(); 55 for(int i=1;i<=n;i++) 56 w[i]=read(); 57 for(int i=1;i<n;i++){ 58 int x(read()),y(read()); 59 g[x].push_back(y),g[y].push_back(x); 60 } 61 dfs(1); 62 printf("%d",my_max(rest[1],w[1])+(n<<1)-2); 63 }
View Code

[補檔][Poi2014]FarmCraft