某收費有線電視網計畫轉播一場重要的足球比賽。他們的轉播網和使用者終端構成一棵樹狀結構,這棵樹的根結點位於足球比賽的現場,樹葉為各個使用者終端,其他中轉站為該樹的內部節點。
從轉播站到轉播站以及從轉播站到所有使用者終端的訊號傳輸費用都是已知的,一場轉播的總費用等於傳輸訊號的費用總和。
現在每個使用者都準備了一筆費用想**這場精彩的足球比賽,有線電視網有權決定給哪些使用者提供訊號而不給哪些使用者提供訊號。
寫乙個程式找出乙個方案使得有線電視網在不虧本的情況下使**轉播的使用者盡可能多。
輸入格式:
輸入檔案的第一行包含兩個用空格隔開的整數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節點與節點之間具有先後的依賴關係,在本題中表現為只有先選擇中轉接點才能訪問到葉子節點。: 複製53
2225
3232
4334
2輸出樣例#
1: 複製
2
以題目給定的樣例為例,如果要訪問3,4節點必須先經過2,在這裡假設f[u][j]為節點為u時選擇前j個節點獲得的最大利潤,以f[1][j]來說,他最多可以選擇的節點分別是3,4,5三個節點,但是3,4這兩個節點必須先經過2。那麼f[1][j]可以表示成:$f[1][j]=max(f[1][j],f[1][j-k]+f[son][k]-edge[1][son])$,其中k表示1的前k個節點,edge[1][son]表示節點1和他的孩子之間的邊。這裡可以看成是節點1選擇k個孩子,但這k個孩子是由下一層節點回溯上來的。
每乙個中轉節點相當於乙個大的揹包,中轉節點的孩子相當於揹包裡面的商品,如果揹包容量為k,那麼可以在這裡揹包裡面選擇1~k個商品。然後中轉節點在向上層節點回溯,最後匯聚到根節點。
初始化每個節點為負無窮大,最後根據根節點f[1][j]來判斷可以有多少孩子滿足條件。
#includeusingnamespace
std;
#define mp make_pair
#define pb push_backvector
int,int> > ed[3005
];int
n,m;
int v[3005
];int f[3005][3005
];int dfs(int
u)
int sum=0
;
for(auto to:ed[u])} }
return
sum;
}int
main()
} for(int i=n-m+1;i<=n;i++) scanf("
%d",&v[i]);
//memset(f,-0x3f3f3f3f,sizeof(f));
fill(f[0],f[0]+3005*3005,-0x3f3f3f3f
);
for(int i=1;i<=n;i++) f[i][0]=0
;
dfs(1);
for(int j=m;j>0;j--)
}return0;
}
題解 P1273 有線電視網
這題顯然是個樹形dp之樹上分組揹包,信心滿滿地寫出轉移方程後,發現 時間複雜度 o n 3 但仔細觀察了討論區和題解後,發現,這是 o n 2 的?於是我開始嘗試牙刷圖 分塊牙刷圖 菊花圖 掃帚圖。卡標算。燃鵝失敗了。證明 暫且先認為所有節點都會產生貢獻,這不會影響最壞複雜。考慮一下最裡面迴圈的過程...
有線電視網 洛谷p1273
某收費有線電視網計畫轉播一場重要的足球比賽。他們的轉播網和使用者終端構成一棵樹狀結構,這棵樹的根結點位於足球比賽的現場,樹葉為各個使用者終端,其他中轉站為該樹的內部節點。從轉播站到轉播站以及從轉播站到所有使用者終端的訊號傳輸費用都是已知的,一場轉播的總費用等於傳輸訊號的費用總和。現在每個使用者都準備...
有線電視網 洛谷 P1273
只能想到n 3的辦法 一看資料量自閉了。看了題解也是n 3 智障出題人 dp i j 代表以i為根的子樹選j個使用者時得到的最大收益 然後就是樹上揹包轉移一下 最後看根節點上最多選幾個人不虧本 include include include using namespace std const int...