1. 程式人生 > >bzoj3573: [Hnoi2014]米特運輸

bzoj3573: [Hnoi2014]米特運輸

tchar cmp pen getchar() 是什麽 AI 啟動 畫圖 while

3573: [Hnoi2014]米特運輸

Time Limit: 20 Sec Memory Limit: 128 MB

Description

米特是D星球上一種非常神秘的物質,蘊含著巨大的能量。在以米特為主要能源的D星上,這種米特能源的運輸和儲 存一直是一個大問題。D星上有N個城市,我們將其順序編號為1到N,1號城市為首都。這N個城市由N-1條單向高速 通道連接起來,構成一棵以1號城市(首部)為根的樹,高速通道的方向由樹中的兒子指向父親。樹按深度分層: 根結點深度為0,屬於第1層;根結點的子節點深度為1,屬於第2層;依此類推,深度為i的結點屬於第i+l層。建好 高速通道之後,D星人開始考慮如何具體地儲存和傳輸米特資源。由於發展程度不同,每個城市儲存米特的能力不 盡相同,其中第i個城市建有一個容量為A[i]的米特儲存器。這個米特儲存器除了具有儲存的功能,還具有自動收 集米特的能力。如果到了晚上六點,有某個儲存器處於未滿的狀態,它就會自動收集大氣中蘊含的米特能源,在早 上六點之前就能收集滿;但是,只有在儲存器完全空的狀態下啟動自動收集程序才是安全的,未滿而又非空時啟動 可能有安全隱患。早上六點到七點間,根節點城市(1號城市)會將其儲存器裏的米特消耗殆盡。根節點不會自動 搜集米特,它只接受子節點傳輸來的米特。早上七點,城市之間啟動米特傳輸過程,傳輸過程逐層遞進:先是第2 層節點城市向第1層(根節點城市,即1號城市)傳輸,直到第1層的儲存器滿或第2層的儲存器全為空;然後是第3 層向第2層傳輸,直到對於第2層的每個節點,其儲存器滿或其予節點(位於第3層)的儲存器全為空;依此類推, 直到最後一層傳輸完成。傳輸過程一定會在晚上六點前完成。 由於技術原因,運輸方案需要滿足以下條件: (1)不能讓某個儲存器到了晚上六點傳輸結束時還處於非空但又未滿的狀態,這個時候儲存器仍然會啟動自動收集 米特的程序,而給已經儲存有米特的儲存器啟動收集程序可能導致危險,也就是說要讓儲存器到了晚上六點時要麽 空要麽滿; (2)關於首都——即1號城市的特殊情況, 每天早上六點到七點間1號城市中的米特儲存器裏的米特會自動被消耗 殆盡,即運輸方案不需要考慮首都的米特怎麽運走; (3)除了1號城市,每個節點必須在其子節點城市向它運輸米特之前將這座城市的米特儲存器中原本存有的米特全部 運出去給父節點,不允許儲存器中殘存的米特與外來的米特發生混合; (4)運向某一個城市的若幹個來源的米特數量必須完全相同,不然,這些來源不同的米特按不同比例混合之後可能 發生危險。 現在D星人已經建立好高速通道,每個城市也有了一定儲存容量的米特儲存器。為了滿足上面的限制條件,可能需 要重建一些城市中的米特儲存器。你可以,也只能,將某一座城市(包括首都)中屎來存在的米特儲存器摧毀,再 新建一座任意容量的新的米特儲存器,其容量可以是小數(在輸入數據中,儲存器原始容量是正整數,但重建後可 以是小數),不能是負數或零,使得需要被重建的米特儲存器的數目盡量少。

Input

第一行是一個正整數N,表示城市的數目。接下來N行,每行一個正整數,其中的第i行表示第i個城市原來存在的米 特儲存器的容量。再接下來是N-I行,每行兩個正整數a,b表示城市b到城市a有一條高速通道(a≠b)。 N<500000,A[j]<10^8

Output

輸出文件僅包含一行,一個整數,表示最少的被重建(即修改儲存器容量)的米特儲存器的數目。

Sample Input

5
5
4
3
2
1
1 2
1 3
2 4
2 5

Sample Output

3

HINT

【樣例解釋】

一個最優解是將A[1]改成8,A[3]改成4,A[5]改成2。這樣,2和3運給1的量相等,4和5運給2的量相等,且每天晚上六點的時候,1,2滿,3,4,5空,滿足所有限制條件。

Source

生平最討厭的就是題目巨長的題了,實在是難以理解;

首先講一下題意:就是在一棵樹上,每個節點有一個權值val[i],要求修改最少的節點權值(權值可以為實數,不能為負數和0),使得每個val[i]=所有兒子節點的權值和;

如果我們確定了一個節點的權值,那麽整個樹都可以知道是什麽樣的了;

然後對於每個節點,如果他兒子有x個,那麽他的每個兒子要*x(自己畫圖試試),這樣一來權值可能會很大,但取個對數就可以了;

最後的ans=n-max(一個數出現的次數);

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4
#include<algorithm> 5 #include<cmath> 6 #define MAXN 2000008 7 using namespace std; 8 9 int tmp,ans,n,m,a[MAXN],d[MAXN],tot,head[MAXN],next[MAXN],vet[MAXN]; 10 double son[MAXN],q[MAXN]; 11 12 inline int read(){ 13 char ch=getchar(); int f=1,x=0; 14 while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();} 15 while(ch>=0&&ch<=9){x=(x<<1)+(x<<3)+ch-0;ch=getchar();} 16 return x*f; 17 } 18 19 void add(int x,int y){ 20 tot++; 21 next[tot]=head[x]; 22 head[x]=tot; 23 vet[tot]=y; 24 } 25 26 void dfs(int u,int fa){ 27 for(int i=head[u];i;i=next[i]){ 28 int y=vet[i]; 29 if(y==fa) continue; 30 son[y]=son[u]+log(d[u]); 31 dfs(y,u); 32 } 33 } 34 35 bool cmp(double aa,double bb){ 36 return aa<bb; 37 } 38 39 int main(){ 40 // freopen("1.in","r",stdin); 41 // freopen("1.out","w",stdout); 42 43 n=read(); 44 for(int i=1;i<=n;i++) 45 a[i]=read(); 46 for(int i=1;i<n;i++){ 47 int x,y; 48 x=read(); y=read(); 49 add(x,y); add(y,x); 50 d[x]++; d[y]++; 51 } 52 son[1]=log(1); 53 for(int i=2;i<=n;i++) d[i]--; 54 dfs(1,0); 55 for(int i=1;i<=n;i++) q[i]=log(a[i])+son[i]; 56 sort(q+1,q+n+1,cmp); 57 q[n+1]=-100000000.0; 58 tmp=1; 59 for(int i=2;i<=n+1;i++){ 60 if(fabs(q[i]-q[i-1])<1e-6) tmp++; 61 else ans=max(ans,tmp),tmp=1; 62 } 63 printf("%d",n-ans); 64 }

bzoj3573: [Hnoi2014]米特運輸