標籤:os ar 不同的 關係 dp 資訊 安全 sp
警衛安排(guard)
【題目描述】
一個重要的基地被分為 n 個連通的地區。出於某種神秘的原因,這些地區以一個地區為核心,呈
一顆樹形分布。
在每個地區安排警衛所需要的費用是不同的,而每個地區的警衛都可以望見其相鄰的地區,只要
一個地區被一個警衛望見或者是安排有警衛,這個地區就是安全的。你的任務是:在確保所有地區都
是安全的情況下,找到安排警衛的最小費用。
【輸入格式】
第一行 n,表示樹中結點的數目。
接下來的 n 行描述了n 個地區的資訊,每一行包含的整數依次為:地區的標號i(0<i<=n),在
地區i 安排警衛的費用k,地區i 的子結點數目m,接下來m 個數為地區i 的子結點編號。
一開始被範例誤導,範例是按照1到n的順序來給資訊的,然後我的輸入也預設成這樣,結果爆0了。修改過後也只過了2個點。雖然培訓時講過這題,但是不自己寫一遍還真是理解不夠透徹。。
F[node][1],F[node][2],F[node][3]分別表示 監控以node為根的樹,在node放警衛/node被他的兒子監控/node被他的父親監控。
F[node][1]=sum{F[node.child][3]}+cost[node];
F[node][2]比較麻煩,首先既然node被兒子管著,那麼有限制“至少有一個兒子是放了警衛的”,因此先假設沒有這個限制,那麼F[node][2]=sum{min{F[node.child][1],F[node.child][2]}},接著枚舉哪個兒子一定放了警衛,假設是編號為k的兒子,那麼F[node][2]還要減去min{F[k][1],F[k][2]}再加上F[k][1];細心的讀者可以發現,這樣其實還不嚴謹,還有可能node本身也放了警衛,因此還要和F[node][1]比較一下取最小值,不過不寫這個也能AC,可能多慮了吧,但是寫進去至少不會錯。
一開始寫成F[node][3]=min{F[node][1],F[node][2]};但仔細揣摩這樣是不對的。node被父親管著,不一定要被他的兒子管著,或者他自己有警衛,比如他自己和兒子都沒警衛,但是兒子的兒子有警衛也是可行的。所以只要考慮他的兒子被管住的情況,也就是F[node][3]=sum{min{F[node.child][1],F[node.child][2]}},再和F[node][1]比較取最小值。
此題不易,必須要有清晰的頭腦才能把關係理清楚。