我們設初始的那個點為root。則所有的藍色鏈都是形如fat
her−
now−
so
nfather-now-son
father
−now
−son
。我們設計兩個dp狀態: dpi
,0
dp_dp
i,0
表示i號點不作為藍色鏈的中間點,dpi
,1
dp_dp
i,1
表示作為中間點。則以下的轉移就非常容易了。
d pi
,0=∑
max(d
pu,1
+w,d
pu,0
)dp_=\sum \max(dp_+w,dp_)
dpi,0
=∑max(dp
u,1
+w,d
pu,0
) dpi
,1=∑
max(d
pu,1
+w,d
pu,0
)+
max
dp_=\sum \max (dp_+w,dp_) + \max\+w - \max (dp_+w,dp_) \}
dpi,1
=∑max(dp
u,1
+w,d
pu,0
)+max
換根dp就ok了。
#include
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define ll long long
#define it iterator
#define pb push_back
#define ii(a,b) make_pair(a,b)
#define fir first
#define sec second
#define freo freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a#define srand mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define all(a) a.begin(),a.end()
#define pob pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using
namespace std;
const
int inf=
0x3f3f3f3f
;typedef pair<
int,
int> mp;
/*}*/
const
int maxn=
200000+20
;int n,rest=
-2e9
,dp[maxn][2
];vector g[maxn]
;void
prework
(int now,
int pre)
dp[now][1
]=max+dp[now][0
];}void
change_root
(int now,
int pre));
dp[now][0
]=0;
for(
auto it:g[now]))
;}check_max
(rest,dp[now][0
]);sort
(all
(v))
,reverse
(all
(v))
;int old=dp[now][0
];for(
auto it:g[now])}
}int
main()
);g[b].pb
();}
prework(1
,0);
change_root(1
,0);
cout
}
P3647 APIO2014 連珠線 換根DP
傳送門 我們通過分析 手動模擬能夠發現,藍線的形態只有兩種 son u 1 u son u 2 和 son u u fa u 對於每乙個節點,要麼是乙個藍線的中點,要麼就是藍線的端點,所以我們設 f u 0 表示 u 為藍線端點時的答案,f u 1 表示 u 作為中點時的答案 轉移方程如下 f u ...
P3647 連珠線 題解
portal 首先它從遊戲開始到結束,是始終只有乙個連通塊的。對於連紅邊,那就直接連就可以了。對於連藍邊,我們首先需要找到一對有紅邊直接相連的點,然後拆散它們把新點插進去,然後仍然是乙個連通塊。稍微等價理解一下,發現其實就是一次連紅邊是從當前連通塊伸出去乙個點 而連藍邊肯定是一下就有兩條,我們把這次...
Luogu P3647 連珠線 題解報告
題目傳送門 題目大意 思路分析 好的這道題目我在換根dp的部分卡了乙個世紀 所以設狀態真的很重要,我因為狀態設的不好,然後換根的時候就很複雜qaq 我來講一下乙個學長 的做法叭qwq 最後的連線情況是一棵樹,首先我們要發現兩個性質,就是在樹中藍線一定是連線在父子之間,並且連續的一段藍線一定為偶數。因...