hdu 3586 樹形dp 二分

2022-06-02 13:57:11 字數 1545 閱讀 5991

題目大意:給定n個敵方據點,1為司令部,其他點各有一條邊相連構成一棵 樹,每條邊都有乙個權值cost表示破壞這條邊的費用,葉子節點為前線。現要切斷前線和司令部的聯絡,每次切斷邊的費用不能超過上限limit,問切斷所 有前線與司令部聯絡所花費的總費用少於m時的最小limit。1<=n<=1000,1<=m<=100萬

題目要問的是最小的最大限制,必然二分答案

然後對於每乙個值,樹形dp判定是否可行

dp[i]表示要切斷以i為根的其它所有子樹的最小代價。

其中設定葉子結點的代價為無窮大

那麼對於某乙個非葉子結點,要切斷一棵子樹就有兩種選擇,切斷以孩子為根的子樹或者切斷根與孩子的邊。

如果根與孩子的邊大於限制,那就取無窮大。

最後判斷1號結點的總花費是否小於等於m

注意:無窮大不要取太大,否則會連續相加溢位

sample input

5 5

1 3 2

1 4 3

3 5 5

4 2 6

0 0sample output

3注意沒結果要輸出-1

inf大小要注意搞好

1 #include2 #include3 #include4 #include5 #include6 #include7 #include8

using

namespace

std;

9#define mod 1000000007

10const

int inf=1000010;11

const

double eps=1e-5

;12 typedef long

long

ll;13

#define cl(a) memset(a,0,sizeof(a))

14#define ts printf("*****\n");

15const

int maxn=1005;16

int n,m,tt,tot=0

,head[maxn],dp[maxn];

17int

maxw;

18struct

edge

19edge[maxn*2

];23

void addedge(int a,int b,int

w)24

30void

init()

3136

void dfs(int u,int pre,int

limit)

3748

if(!flag) dp[u]=inf; //

葉子不能切哦49}

50int

main()

5168

int l=1,r=maxw;

69int ans=-1;70

while(l<=r)

7180

else l=mid+1;81

}82 printf("

%d\n

",ans);83}

84 }

hdu 3586 樹形dp 二分

題意 給n個節點的樹,要求使葉子節點與根斷開,割掉的邊的權值和不超過m。求這些被割邊的權值最大中的最小。dp u min dp v w w 為 u 到 v 的權值。如果w 大於二分的 mid dp u dp v 二分列舉邊權。include include include includeusing ...

hdu 2604 DP 矩陣二分

實際上就是這樣乙個問題,乙個序列僅由1和0組成,問n位不帶101和111子串行有多少個,結果模m 話說這是集訓的一道題,當時完全沒思路,今天做了一下,還是沒有做出來,不過好歹還會用最裸的記憶化搜尋。但肯定超時 話說集訓那時真的弱爆了。超弱的1b 看了下解題報告,發現1維dp既能搞定,再用矩陣二分。其...

hdu 1025 dp 二分 模板

題意 在一條河的兩邊各有n個位置,在這些位置之間建橋,要求所有橋之間不能交叉。現在告訴你所有可以建橋的位置,例如2,4,就是說河左邊的位置2可以與河右邊的位置4之間建橋,現在要求滿足要求的情況下最多可以建橋的個數。分析 想了好久發現是乙個最長上公升子串行問題,當時n比較大,所以一般的dp演算法不能解...