題面
題目背景
bob 喜歡玩電腦遊戲,特別是戰略遊戲。但是他經常無法找到快速玩過遊戲的辦法。現在他有個問題。
題目描述
他要建立乙個古城堡,城堡中的路形成一棵無根樹。他要在這棵樹的結點上放置最少數目的士兵,使得這些士兵能瞭望到所有的路。
注意,某個士兵在乙個結點上時,與該結點相連的所有邊將都可以被瞭望到。
請你編一程式,給定一樹,幫 bob 計算出他需要放置最少的士兵。
輸入格式
第一行乙個整數\(n\),表示樹中結點的數目。
第二行至第\(n+1\) 行,每行描述每個結點資訊,依次為:乙個整數\(i\),代表該結點標號,乙個自然數 \(k\),代表後面有\(k\) 條無向邊與結點 \(i\) 相連。接下來 \(k\) 個整數,分別是每條邊的另乙個結點標號 \(r_1,r_2,\cdots,r_k\),表示 \(i\)與這些點間各有一條無向邊相連。
對於乙個\(n\) 個結點的樹,結點標號在 \(0\) 到 \(n-1\) 之間,在輸入資料中每條邊只出現一次。保證輸入是一棵樹。
輸出格式
輸出檔案僅包含乙個整數,為所求的最少的士兵數目。
輸入輸出樣例
輸入 #1複製
4
0 1 1
1 2 2 3
2 03 0
輸出 #1複製
1
說明/提示
資料規模與約定
對於全部的測試點,保證 \(1 \leq n \leq 1500\)
題解因為是樹形結構,並且因為是求最值的問題,所以我們就想到了用樹形\(dp\)去做這道題
一般以節點的深淺(子樹從小到大)的順序作為\(dp\)的階段,\(dp\)的狀態表示中,第一維通常是節點的
編號,(代表以該節點為根的子樹)
所以我們設\(f[i][0/1]\)表示該節點放還是不放士兵
根據題意,如果當前的節點不放士兵,那麼它的子節點必須全部放置士兵,因為要滿足士兵可以看到所
有的邊。因此我們有狀態轉移方程\(f[u][0]+=f[v][1]\)(其中v是u的子節點)
如果當前的節點放置
那麼我們可以取最小值\(f[u][1]+=min(f[v][0],f[v][1])\)
注意:可以選擇任意乙個節點為根,答案都是一樣的
最後我們的答案就是\(min(f[選擇的節點][1],f[選擇的節點][0])\)
**
#includeusing namespace std;
const int n=50000;
int f[n][2];
int n;
int din[n];
int ne[n],ver[n],head[n],idx;
void add(int x,int y)
void dp(int x,int father)
}int main()
}dp(0,-1);
cout
}
P2016 戰略遊戲
樹形dp f u 0 表示 uf u 0 表示u f u 0 表示u 號節點不放士兵,以x為根的子樹需要的最少士兵數。f u 1 表示 uf u 1 表示u f u 1 表示u 號節點放士兵,以x為根的子樹需要的最少士兵數。由於我們定義的是將其完全覆蓋,則我們不需要考慮父親節點,為什麼?當我們已經回...
題解 P2016 戰略遊戲
題目 解法跟 dalao real ljs 類似,但沒有用到遞迴 題目相當於需要求覆蓋這顆樹需要的最小點數 用 dp 表示在這棵樹中,以 i 為根節點的子樹在選 不選根節點的情況下,覆蓋這棵樹所有邊需要的最小點數 所以,當不選這個節點 i 時,則所有 以其子節點為根節點的子樹 都必選根節點 當選擇這...
洛谷 P2016 戰略遊戲
題目描述 bob喜歡玩電腦遊戲,特別是戰略遊戲。但是他經常無法找到快速玩過遊戲的辦法。現在他有個問題。他要建立乙個古城堡,城堡中的路形成一棵樹。他要在這棵樹的結點上放置最少數目的士兵,使得這些士兵能瞭望到所有的路。注意,某個士兵在乙個結點上時,與該結點相連的所有邊將都可以被瞭望到。請你編一程式,給定...