題目大意:某收費有線電視網計畫轉播一場重要的足球比賽。他們的轉播網和使用者終端構成一棵樹狀結構,這棵樹的根結點位於足球比賽的現場,樹葉為各個使用者終端,其他中轉站為該樹的內部節點。
從轉播站到轉播站以及從轉播站到所有使用者終端的訊號傳輸費用都是已知的,一場轉播的總費用等於傳輸訊號的費用總和。
現在每個使用者都準備了一筆費用想**這場精彩的足球比賽,有線電視網有權決定給哪些使用者提供訊號而不給哪些使用者提供訊號。
寫乙個程式找出乙個方案使得有線電視網在不虧本的情況下使**轉播的使用者盡可能多。
使得有線電視網在不虧本的情況下意指在總花費小於等於利潤的情況下可以通知幾個點。小於等於利潤不好搞,可以倒過來,路徑邊權為正數,終端葉子結點點權為負數。然後dp到根節點完,遍歷根節點通知的終點結點個數為i時的最小花費p,當p小於等於0時,i是乙個有效解。
設dp[u][i]為u結點往下通知i個終端結點的費用,列舉在子樹中通知k個終端結點的費用對dp[u][i]進行更新,
dp[u][i]=min(dp[u][i],dp[u][i-k]+dp[v][k]+w),dfs完求出根節點所有狀態最優解後,列舉根節點通知個數,看是否費用小於等於0,得出最優解。
由於滾動掉了一維,原狀態為dp[u][i][j] 表示u結點僅用前i個結點通知j個結點的最小費用,轉移時需要倒過來,那麼轉移的上界可以從m開始,也可以用sz[u] 陣列,邊dfs邊求出當前結點最多能通知的終端結點人數,轉移上界降為sz[u],同理子節點轉移上界降為sz[v]
#include
using
namespace std;
#define pii pair
const
int maxn =
3e3+10;
const
int mod =
998244353
;int n,m;
vector g[maxn]
;int val[maxn]
;int num[maxn]
;int dp[maxn]
[maxn]
;voiddp(
int s)
}int
main()
}memset
(dp,
0x3f3f3f3f
,sizeof
(dp));
for(
int i = n-m+
1; i <= n; i++
)scanf
("%d"
,&val[i]);
dp(1)
;int mx =0;
for(
int i =
0; i <= m; i++)if
(dp[1]
[i]<=
0) mx=i;
printf
("%d\n"
,mx)
;}
有線電視網 洛谷p1273
某收費有線電視網計畫轉播一場重要的足球比賽。他們的轉播網和使用者終端構成一棵樹狀結構,這棵樹的根結點位於足球比賽的現場,樹葉為各個使用者終端,其他中轉站為該樹的內部節點。從轉播站到轉播站以及從轉播站到所有使用者終端的訊號傳輸費用都是已知的,一場轉播的總費用等於傳輸訊號的費用總和。現在每個使用者都準備...
有線電視網 洛谷 P1273
只能想到n 3的辦法 一看資料量自閉了。看了題解也是n 3 智障出題人 dp i j 代表以i為根的子樹選j個使用者時得到的最大收益 然後就是樹上揹包轉移一下 最後看根節點上最多選幾個人不虧本 include include include using namespace std const int...
有線電視網 洛谷P1273
題目描述 某收費有線電視網計畫轉播一場重要的足球比賽。他們的轉播網和使用者終端構成一棵樹狀結構,這棵樹的根結點位於足球比賽的現場,樹葉為各個使用者終端,其他中轉站為該樹的內部節點。從轉播站到轉播站以及從轉播站到所有使用者終端的訊號傳輸費用都是已知的,一場轉播的總費用等於傳輸訊號的費用總和。現在每個使...