题解 P3931 【SAC E#1 - 一道难题 Tree】
唔嗯,只是提供一个新的思路。
随机跳题跳到了这题,觉得有点意思就花了
题目意思就是让从根到每个叶子的路径上有至少一条边被割。那么不妨设计一个zz状态
其中
也就是说我们可以通过删掉
下面说一下聚合分析出来的复杂度。不妨令
那么对于每个
于是最后的复杂度为
233就当顺便练练复杂度分析了。
void dfs(int u, int fr){
bool fg = 1 ;
dfn[u] = ++ Id, sz[u] = 1, fa[u] = fr ;
for (int k = head[u] ; k ; k = next(k)){
if (to(k) == fr) continue ;
fg = 0, cost[to(k)] = val(k) ;
dfs(to(k), u), sz[u] += sz[to(k)], ctn[u] += ctn[to(k)] ;
}
if (fg) Ls[++ tot] = u, ctn[u] = 1 ;
}
int main(){
cin >> N >> rt ; int i, j, u, v ;
for (i = 1 ; i < N ; ++ i)
u = qr(), v = qr(), j = qr(), add(u, v, j) ;
dfs(rt, 0) ;
for (i = 1 ; i <= tot ; ++ i){
int n = Ls[i], nid = dfn[n] ;
f[i] = f[i - 1] + cost[Ls[i]] ;
while (fa[n]){
if (fa[n] != rt && nid == dfn[fa[n]] + sz[fa[n]] - 1)
f[i] = min(f[i], f[i - ctn[fa[n]]] + cost[fa[n]]) ;
else break ;
n = fa[n] ;
}
}
cout << f[tot] << endl ; return 0 ;
}