BZOJ 3573 米特运输
Description
米特是D星球上一種非常神秘的物質(zhì),蘊含著巨大的能量。在以米特為主要能源的D星上,這種米特能源的運輸和儲存一直是一個大問題。
??? D星上有N個城市,我們將其順序編號為1到N,1號城市為首都。這N個城市由N-1條單向高速通道連接起來,構(gòu)成一棵以1號城市(首部)為根的樹,高速通道的方向由樹中的兒子指向父親。樹按深度分層:根結(jié)點深度為0,屬于第1層;根結(jié)點的子節(jié)點深度為1,屬于第2層;依此類推,深度為i的結(jié)點屬于第i+l層。
??? 建好高速通道之后,D星人開始考慮如何具體地儲存和傳輸米特資源。由于發(fā)展程度不同,每個城市儲存米特的能力不盡相同,其中第i個城市建有一個容量為A[i]的米特儲存器。這個米特儲存器除了具有儲存的功能,還具有自動收集米特的能力。如果到了晚上六點,有某個儲
存器處于未滿的狀態(tài),它就會自動收集大氣中蘊含的米特能源,在早上六點之前就能收集滿;但是,只有在儲存器完全空的狀態(tài)下啟動自動收集程序才是安全的,未滿而又非空時啟動可能有安全隱患。早上六點到七點間,根節(jié)點城市(1號城市)會將其儲存器里的米特消耗殆盡。
根節(jié)點不會自動搜集米特,它只接受子節(jié)點傳輸來的米特。早上七點,城市之間啟動米特傳輸過程,傳輸過程逐層遞進:先是第2層節(jié)點城市向第1層(根節(jié)點城市,即1號城市)傳輸,直到第1層的儲存器滿或第2層的儲存器全為空;然后是第3層向第2層傳輸,直到對于第2層的每個節(jié)點,其儲存器滿或其予節(jié)點(位于第3層)的儲存器全為空;依此類推,直到最后一層傳輸完成。傳輸過程一定會在晚上六點前完成。
??? 由于技術(shù)原因,運輸方案需要滿足以下條件:
(1)不能讓某個儲存器到了晚上六點傳輸結(jié)束時還處于非空但又未滿的狀態(tài),這個時候儲存器仍然會啟動自動收集米特的程序,而給已經(jīng)儲存有米特的儲存器啟動收集程序可能導(dǎo)致危險,也就是說要讓儲存器到了晚上六點時要么空要么滿;
(2)關(guān)于首都——即1號城市的特殊情況,? 每天早上六點到七點間1號城市中的米特儲存器里的米特會自動被消耗殆盡,即運輸方案不需要考慮首都的米特怎么運走;
(3)除了1號城市,每個節(jié)點必須在其子節(jié)點城市向它運輸米特之前將這座城市的米特儲存器中原本存有的米特全部運出去給父節(jié)點,不允許儲存器中殘存的米特與外來的米特發(fā)生混合;
(4)運向某一個城市的若干個來源的米特數(shù)量必須完全相同,不然,這些來源不同的米特按不同比例混合之后可能發(fā)生危險。
??? 現(xiàn)在D星人已經(jīng)建立好高速通道,每個城市也有了一定儲存容量的米特儲存器。為了滿足上面的限制條件,可能需要重建一些城市中的米特儲存器。你可以,也只能,將某一座城市(包括首都)中屎來存在的米特儲存器摧毀,再新建一座任意容量的新的米特儲存器,其容量可以是小數(shù)(在輸入數(shù)據(jù)中,儲存器原始容量是正整數(shù),但重建后可以是小數(shù)),不能是負數(shù)或零,使得需要被重建的米特儲存器的數(shù)目盡量少。
Input
??? 第一行是一個正整數(shù)N,表示城市的數(shù)目。
??? 接下來N行,每行一個正整數(shù),其中的第i行表示第i個城市原來存在的米特儲存器的容量。
??? 再接下來是N-I行,每行兩個正整數(shù)a,b表示城市b到城市a有一條高速通道(a≠b)。
Output
??? 輸出文件僅包含一行,一個整數(shù),表示最少的被重建(即修改儲存器容量)的米特儲存器的數(shù)目。
Sample Input
5
5
4
3
2
I
12
13
24
25
Sample Output
3HINT
?
【樣例解釋】
? 一個最優(yōu)解是將A[1]改成8,A[3]改成4,A[5]改成2。這樣,2和3運給1的量相等,4和5運
給2的量相等,且每天晚上六點的時候,1,2滿,3,4,5空,滿足所有限制條件。
??
? 對于100%的數(shù)據(jù)滿足N<500000,A[j]<10^8
?
Source
別人都說讀懂了題目是到水題,但是我做并沒有想象中那么水啊,我還是翻了題解的。。。QAQ,一定是我太弱了。。。
其實做法還是很好理解的。任意兩個點的倍率關(guān)系是確定的(若a是b的孩子,b又有k個孩子,則A[b]=k*A[a],利用這個關(guān)系可以推出任意兩個點的關(guān)系。做的時候腦袋蠢了,沒有想到這一點)。設(shè)dis[i]為修改后A[1]=dis[i]*A[i],那么依題意當(dāng)a不修改時b不修改當(dāng)且僅當(dāng)A[a]*dis[a]=A[b]*dis[b],因此我們就可以反過來想。求最少修改的不就是求最多的不修改的嗎???我們知道所有的A[i]*dis[i],看哪一個值最多就可以了。
但是dis數(shù)組值有可能會很大,我們有兩種應(yīng)對的策略——(取對數(shù)再sort(取對數(shù)是個很重要的處理方法),哈希)。
?
1 #include<algorithm> 2 #include<cmath> 3 #include<vector> 4 #include<iostream> 5 #include<cstdio> 6 #include<cstdlib> 7 using namespace std; 8 9 typedef long double ld; 10 #define maxn (500010) 11 #define inf (1 << 30) 12 #define eps (1e-11) 13 int n,next[maxn<<1],toit[maxn<<1],fa[maxn]; 14 int side[maxn],cnt,team[maxn],d[maxn]; 15 ld A[maxn],dis[maxn],bac[maxn]; bool in[maxn]; 16 17 inline bool equal(ld a,ld b) { return fabs(a-b) <= eps; } 18 19 inline void add(int a,int b) { next[++cnt] = side[a]; side[a] = cnt; toit[cnt] = b; } 20 21 inline void ins(int a,int b) { add(a,b); add(b,a); } 22 23 inline void bfs() 24 { 25 int h = 0,t = 0; 26 in[1] = true; team[++t] = 1; 27 while (h != t) 28 { 29 int now = team[++h]; 30 for (int i = side[now];i;i = next[i]) 31 if (!in[toit[i]]) 32 in[toit[i]] = true,team[++t] = toit[i],fa[toit[i]] = now,++d[now]; 33 } 34 for (int i = 2;i <= n;++i) 35 dis[team[i]] = dis[fa[team[i]]] + log(d[fa[team[i]]]); 36 } 37 38 inline void work() 39 { 40 int res = 1,cnt; ld last = -1; 41 for (int i = 1;i <= n;++i) bac[i] = dis[i] + A[i]; 42 sort(bac+1,bac+n+1); 43 for (int i = 1;i <= n;++i) 44 { 45 if (equal(bac[i],last)) res = max(res,++cnt); 46 else last = bac[i],cnt = 1; 47 } 48 printf("%d",n-res); 49 } 50 51 int main() 52 { 53 freopen("3573.in","r",stdin); 54 freopen("3573.out","w",stdout); 55 int a,b; scanf("%d",&n); 56 for (int i = 1;i <= n;++i) scanf("%d",&a),A[i] = log(a); 57 for (int i = 1;i < n;++i) scanf("%d %d",&a,&b),ins(a,b); 58 bfs(); work(); 59 fclose(stdin); fclose(stdout); 60 return 0; 61 }View Code
?
轉(zhuǎn)載于:https://www.cnblogs.com/mmlz/p/4297671.html
總結(jié)
以上是生活随笔為你收集整理的BZOJ 3573 米特运输的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: cf 414B Mashmokh and
- 下一篇: UIScrollView