P2607(基環樹 樹形DP)

2021-09-24 13:22:53 字數 1024 閱讀 2566

最近想要刷部落格數,給自己一種努力的假象,最好的方式當然是給做過的題目做一篇題解啦

標準樹形dp題,選了父節點不能選子節點,唯一難點是基環樹的處理

先找環,只需要找到環上的兩個點就行了,其他點不用一起找出,用dfs,斷邊

斷邊的具體操作是:分別將邊上的兩個點設為根進行樹形dp,但兩個點之間還有的關係怎麼辦呢,就每一次強制不選根節點,然後比較兩次dp的結果,選取最大的那個

#include

using namespace std;

#define ll long long

const

int m=

1000005

;#define inf 20000000

struct e

edge[m]

;int head[m]

,fa[m]

,n,cnt=

0,root,vis[m]

;ll val[m]

,dp[m][2

],ans1=0;

void

add_edge

(int from,

int to)

void

shudp

(int m)

else}}

void

find_root

(int m)

root=m;

shudp

(root)

; ll t=

max(dp[m][0

],dp[m][1

]); root=fa[root]

;shudp

(root)

; ans1+

=max

(t,max

(dp[root][1

],dp[root][0

]));

}int

main()

for(

int i=

1;i<=n;i++)}

cout<}

洛谷P2607 騎士 樹形dp

思路 首先我們想到可以對相互憎惡的倆個騎士連邊,這樣就得到了乙個圖,有多個連通塊,並且每個連通塊中最多只有乙個環。如果每個連通塊都是一顆樹,那麼這個問題就很簡單 每個節點都是選或者不選。idea1 我想可不可以把這個比樹多一條邊的圖,變成一棵樹來處理,那麼就是要刪掉環上的一條邊。考慮刪掉這條邊 u,...

洛谷2607 騎士(基環樹 樹形DP)

第一眼 咦這不簡單樹形dp嗎?第二眼 嗯?這不是有n條邊嗎?怎麼就樹形dp了?第三眼 唉好像拆一條邊不就n 1條邊了嗎?哎嘿嘿我太聰明了。噼里啪啦打完一交,wa完。一臉懵?才發現可能直接將整個圖 以為保證連通 拆成兩個聯通塊了。然後畫畫圖,發現肯定是拆環上的邊,搞個並查集記錄一下好了。然後對於拆掉的...

P2607 ZJOI2008 騎士(基環樹)

邊數等於點數,是基環樹。考慮dp,如果是樹的話,轉移方程為dp u 1 選擇u w u dp v 0 v為u的子節點 dp u 0 不選擇u max dp v 0 dp v 1 然後基環樹只要找到環後,斷開環上的一條邊就成了樹。斷開的邊上兩端點不能同時選擇,所以對於每棵基環樹,我們求兩邊dp,分別限...