某收費有線電視網計畫轉播一場重要的足球比賽。他們的轉播網和使用者終端構成一棵樹狀結構,這棵樹的根結點位於足球比賽的現場,樹葉為各個使用者終端,其他中轉站為該樹的內部節點。
從轉播站到轉播站以及從轉播站到所有使用者終端的訊號傳輸費用都是已知的,一場轉播的總費用等於傳輸訊號的費用總和。
現在每個使用者都準備了一筆費用想**這場精彩的足球比賽,有線電視網有權決定給哪些使用者提供訊號而不給哪些使用者提供訊號。
寫乙個程式找出乙個方案使得有線電視網在不虧本的情況下使**轉播的使用者盡可能多。
輸入格式:
輸入檔案的第一行包含兩個用空格隔開的整數n和m,其中2≤n≤3000,1≤m≤n-1,n為整個有線電視網的結點總數,m為使用者終端的數量。
第乙個轉播站即樹的根結點編號為1,其他的轉播站編號為2到n-m,使用者終端編號為n-m+1到n。
接下來的n-m行每行表示—個轉播站的資料,第i+1行表示第i個轉播站的資料,其格式如下:
k a1 c1 a2 c2 … ak ck
k表示該轉播站下接k個結點(轉播站或使用者),每個結點對應一對整數a與c,a表示結點編號,c表示從當前轉播站傳輸訊號到結點a的費用。最後一行依次表示所有使用者為**比賽而準備支付的錢數。
輸出格式:
輸出檔案僅一行,包含乙個整數,表示上述問題所要求的最大使用者數。
輸入樣例#1:複製
5 3
2 2 2 5 3
2 3 2 4 3
3 4 2
輸出樣例#1:複製
2
樣例解釋
如圖所示,共有五個結點。結點①為根結點,即現場直播站,②為乙個中轉站,③④⑤為使用者端,共m個,編號從n-m+1到n,他們為**比賽分別準備的錢數為3、4、2,從結點①可以傳送訊號到結點②,費用為2,也可以傳送訊號到結點⑤,費用為3(第二行資料所示),從結點②可以傳輸訊號到結點③,費用為2。也可傳輸訊號到結點④,費用為3(第三行資料所示),如果要讓所有使用者(③④⑤)都能看上比賽,則訊號傳輸的總費用為:
2+3+2+3=10,大於使用者願意支付的總費用3+4+2=9,有線電視網就虧本了,而只讓③④兩個使用者看比賽就不虧本了。
樹形揹包dp的典型例題
明確dp[i][j]含義,表示i節點,選j個使用者,能得到的錢的最大值,然後對每個節點做分組揹包。
首先,揹包的總容量相當於該點為根節點的子樹中所有的使用者數量(dp[i][j]的 j 不可能超過它連線的所有使用者數)。然後,把該節點的每個兒子看成一組,每組中的元素為選乙個,選兩個...選n個使用者。
轉移方程 dp[i][j]=max(dp[i][j],dp[i][j-k]+dp[v][k]-這條邊的花費) i,j不解釋了,v表示列舉到這一組(即i的兒子),k表示列舉到這組中的元素:選k個使用者。
最後輸出dp[1][i]>=0的i的最大值,所以反向列舉。
簡單來說就是把每個節點看成乙個揹包啦,它的容量就是以這個節點為根的子樹大小,組數就是連線的兒子個數。
每組都有很多選擇,選乙個,兩個,三個使用者,把這些選擇當做組中的元素就好了,容易看出每組中只能選乙個元素,比如你選擇了選乙個使用者,就不可能同時選擇選兩個使用者。
#include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std;
const int n=3010;
struct node
edge[n*2];///無向邊,2倍
int head[n];///head[u]=i表示以u為起點的所有邊中的第一條邊是 i號邊
int tot; ///總邊數
int minn;
int v[n],num[n];
void add(int u,int v,int w)
int n,m;
int dp[n][n];
void dfs(int u,int fa)
for(int i=head[u];i!=-1;i=edge[i].next)
}}int main() }
for(int i=n-m+1;i<=n;i++)
scanf("%d",&v[i]);
dfs(1,-1);
for (int i=n;i>=1;i--)
if (dp[1][i]>=0)
return 0;
}
POJ 1155 TELE 樹形揹包
1為根節點,有m個葉節點,其他為中間結點,每個結點的權值代表他願意付出的錢,邊的權值代表聯通兩節點的代價,求不虧損的情況下最多能到達多少個葉節點。另dp u i 表示根節點為u的子樹此時裝了i個葉節點的盈利情況 m oney i e dgec osti 那麼我們就能得到這樣的狀態轉移方程 如果u是葉...
poj1155 TELE(樹形 揹包dp)
題意 某電台要廣播一場比賽,該電台網路是由n個網點組成的一棵樹,其中m個點為客戶端,其餘點為 站。客戶端i願支付的錢為pay i 每一條邊需要的花費固定,問電台在保證不虧損的情況下,最多能使多少個客戶端接收到資訊?思路 設dp i j 表示i節點為根節點並且子樹已經有j個使用者的時候最大剩餘費用。那...
POJ 1155 TELE 樹形揹包問題
題目描述看的莫名其妙,很久才看懂。就是很裸的樹形揹包問題吧,狀態是dp i,j 表示節點i取到j個客戶能得到的最大收益。注意一開始初始化的時候所有j為0的時候應該是0,然後其他值都要初始化成負無窮,因為收益有可能是負值。然後做01揹包的時候注意方向,防止出現取某乙個元素多次 include incl...