最近想要刷部落格數,給自己一種努力的假象,最好的方式當然是給做過的題目做一篇題解啦
標準樹形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,分別限...