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

2021-09-30 16:59:01 字數 969 閱讀 1755

第一眼:咦這不簡單樹形dp嗎?

第二眼:嗯?這不是有n條邊嗎?怎麼就樹形dp了?

第三眼:唉好像拆一條邊不就n-1條邊了嗎?哎嘿嘿我太聰明了。。。。

噼里啪啦打完一交,wa完。。。。。。。一臉懵???才發現可能直接將整個圖(以為保證連通)拆成兩個聯通塊了。。。。。

然後畫畫圖,發現肯定是拆環上的邊,搞個並查集記錄一下好了。

然後對於拆掉的邊,直接分別強制兩端點不選做一遍樹形dp即可,取個較大值。考慮dp,每個點就兩個選擇:選和不選。如果不選,那麼當前點最大值就為所有兒子的最大值之和;如果選,那麼當前點最大值就為所有兒子的不選的最大值之和。

**啪改完又交上去,對了三個點,一臉懵。

所以就可能要多次拆邊,要開陣列記錄。每組都要做一遍,最後答案為各組最大值之和。

#includeusing namespace std;

typedef long long ll;

const int maxn=1e6+10;

const int maxm=2e6+10;

int n,cnt;

int s[maxn],t[maxn],tot;

ll ans;

int head[maxn];

int nxt[maxm],to[maxm];

int a[maxn];

ll dpfa[maxn],dpson[maxn];

int fa[maxn];

int read()

int find(int x)

void add(int x,int y)

void dfs(int u,int f)

}int main()

for(int i=1;i<=n;++i)

else

} ll tt;

for(int i=1;i<=tot;++i)

cout

}

洛谷P2607 騎士 樹形dp

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

P2607(基環樹 樹形DP)

最近想要刷部落格數,給自己一種努力的假象,最好的方式當然是給做過的題目做一篇題解啦 標準樹形dp題,選了父節點不能選子節點,唯一難點是基環樹的處理 先找環,只需要找到環上的兩個點就行了,其他點不用一起找出,用dfs,斷邊 斷邊的具體操作是 分別將邊上的兩個點設為根進行樹形dp,但兩個點之間還有的關係...

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,分別限...