BZOJ 1596--電話網絡(樹形DP)
阿新 • • 發佈:2017-11-25
div 計算 mst .com arm page 2個 ssa 樹形
Submit: 1139 Solved: 534
[Submit][Status][Discuss]
* 第1行: 1個整數,N
* 第2..N行: 每行為2個用空格隔開的整數A、B,為兩塊相鄰草地的編號
1 3
5 2
4 3
3 5
輸入說明:
Farmer John的農場中有5塊草地:草地1和草地3相鄰,草地5和草地2、草地
4和草地3,草地3和草地5也是如此。
輸出說明:
FJ可以選擇在草地2和草地3,或是草地3和草地5上建通訊塔。
1596: [Usaco2008 Jan]電話網絡
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1139 Solved: 534
[Submit][Status][Discuss]
Description
Farmer John決定為他的所有奶牛都配備手機,以此鼓勵她們互相交流。不過,為此FJ必須在奶牛們居住的N(1 <= N <= 10,000)塊草地中選一些建上無線電通訊塔,來保證任意兩塊草地間都存在手機信號。所有的N塊草地按1..N 順次編號。 所有草地中只有N-1對是相鄰的,不過對任意兩塊草地A和B(1 <= A <= N; 1 <= B <= N; A != B),都 可以找到一個以A開頭以B結尾的草地序列,並且序列中相鄰的編號所代表的草地相鄰。無線電通訊塔只能建在草地 上,一座塔的服務範圍為它所在的那塊草地,以及與那塊草地相鄰的所有草地。 請你幫FJ計算一下,為了建立能 覆蓋到所有草地的通信系統,他最少要建多少座無線電通訊塔。Input
Output
* 第1行: 輸出1個整數,即FJ最少建立無線電通訊塔的數目
Sample Input
51 3
5 2
4 3
3 5
輸入說明:
Farmer John的農場中有5塊草地:草地1和草地3相鄰,草地5和草地2、草地
4和草地3,草地3和草地5也是如此。
Sample Output
2輸出說明:
FJ可以選擇在草地2和草地3,或是草地3和草地5上建通訊塔。
題目鏈接:
http://www.lydsy.com/JudgeOnline/problem.php?id=1596
Solution
簡單的樹形DP。。。
dp [ 0 / 1 ] [ i ] 表示第 i 個點沒有/有 建立無線電通訊塔時,使以i為根的子樹被完全覆蓋的最小數量。。
狀態轉移方程顯然。。。
代碼
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<iostream> #define N 10010 #define E 20020 using namespace std; int n,cnt; int head[N],dp[N][3]; struct edge{ int r,next; }e[E]; void insert(int u,int v){ e[++cnt].r=v; e[cnt].next=head[u]; head[u]=cnt; } void tree_DP(int x,int F){ int sum=0; dp[x][1]=1;dp[x][0]=N; for(int i=head[x];i>0;i=e[i].next) if(e[i].r!=F){ tree_DP(e[i].r,x); dp[x][1]+=min(dp[e[i].r][0],min(dp[e[i].r][1],dp[e[i].r][2])); dp[x][2]+=dp[e[i].r][0]; sum+=min(dp[e[i].r][0],dp[e[i].r][1]); } for(int i=head[x];i>0;i=e[i].next) if(e[i].r!=F) dp[x][0]=min(dp[x][0],dp[e[i].r][1]+sum-min(dp[e[i].r][0],dp[e[i].r][1])); } int main(){ int x,y,ans; cnt=0; scanf("%d",&n); for(int i=1;i<n;i++){ scanf("%d%d",&x,&y); insert(x,y); insert(y,x); } tree_DP(1,0); ans=min(dp[1][0],dp[1][1]); printf("%d\n",ans); return 0; }
This passage is made by Iscream-2001.
BZOJ 1596--電話網絡(樹形DP)