警卫站岗(树上dp)
題目描述
五一來臨,某地下超市為了便于疏通和指揮密集的人員和車輛,以免造成超市內(nèi)的混亂和擁擠,準(zhǔn)備臨時從外單位調(diào)用部分保安來維持交通秩序。
已知整個地下超市的所有通道呈一棵樹的形狀;某些通道之間可以互相望見。總經(jīng)理要求所有通道的每個端點(diǎn)(樹的頂點(diǎn))都要有人全天候看守,在不同的通道端點(diǎn)安排保安所需的費(fèi)用不同。
一個保安一旦站在某個通道的其中一個端點(diǎn),那么他除了能看守住他所站的那個端點(diǎn),也能看到這個通道的另一個端點(diǎn),所以一個保安可能同時能看守住多個端點(diǎn)(樹的結(jié)點(diǎn)),因此沒有必要在每個通道的端點(diǎn)都安排保安。
任務(wù):
請你幫助超市經(jīng)理策劃安排,在能看守全部通道端點(diǎn)的前提下,使得花費(fèi)的經(jīng)費(fèi)最少。
解析
樹上dp
狀態(tài)定義:𝑓[𝑥][0/1/2]分別對應(yīng)以下三種情況:
0.x節(jié)點(diǎn)被自己覆蓋,即選擇x點(diǎn)來覆蓋x點(diǎn)
1.x節(jié)點(diǎn)被兒子y覆蓋,即選擇y點(diǎn)來覆蓋x點(diǎn)
2.x節(jié)點(diǎn)被父親fa覆蓋,即選擇fa點(diǎn)來覆蓋x點(diǎn)
轉(zhuǎn)移為:
𝑓[𝑥][0]=∑ min?(𝑓[𝑦][0],𝑓[𝑦][1],𝑓[𝑦][2]) + 𝑣𝑎𝑙[𝑥] 𝑓[𝑥][2]=∑ min?(𝑓[𝑦][0],𝑓[𝑦][1]) 𝑓[𝑥][1]=∑ min?(𝑓[𝑦][0],𝑓[𝑦][1]) 第三種如果選擇的全部都是𝑓[𝑦][1],要再加上min?(𝑓[𝑦][0]?𝑓[𝑦][1])然后就完事了
代碼
#include <bits/stdc++.h> using namespace std; const int N=1800; int n,m; /* op=0 被自己覆蓋 op=1 被兒子覆蓋 op=2 被父親覆蓋 */ struct node{int to,nxt; }p[N]; int fi[N],cnt=-1,ru[N]; int v[N]; void addline(int x,int y){p[++cnt]=(node){y,fi[x]};fi[x]=cnt; } int a,b,c; int dp[N][5]; int find(int x,int op){if(dp[x][op]) return dp[x][op];int ans=0; // printf("op=%d\n",op);if(op==0){ans=v[x];for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;ans+=min(find(to,0),min(find(to,1),find(to,2)));} // printf("%d %d %d\n",x,op,ans);return dp[x][op]=ans;}else if(op==2){for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;ans+=min(find(to,0),find(to,1));} // printf("%d %d %d\n",x,op,ans);return dp[x][op]=ans;}else if(op==1){int flag=1,mn=2e9;for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;if(find(to,0)<find(to,1)) flag=0;if(flag){mn=min(mn,find(to,0)-find(to,1));}ans+=min(find(to,0),find(to,1));}if(flag) ans+=mn; // printf("%d %d %d\n",x,op,ans);return dp[x][op]=ans;} } int main(){memset(fi,-1,sizeof(fi));scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d%d%d",&a,&b,&c);v[a]=b;for(int j=1;j<=c;j++){scanf("%d",&b);addline(a,b);ru[b]++;}}for(int i=1;i<=n;i++){if(ru[i]==0){printf("%d",min(find(i,0),find(i,1)));break;}}return 0; } /* 6 1 30 3 2 3 4 2 16 2 5 6 3 5 0 4 4 0 5 11 0 6 5 0 */總結(jié)
以上是生活随笔為你收集整理的警卫站岗(树上dp)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不止代码:洛谷P1064 金明的预算方案
- 下一篇: 洛谷P4322 最佳团伙(树上dp)