Brief description:
给定一棵 n 个点的点权树,同时结点分为黑点和白点两类。
要求找到一条长度最大的路径,使得路径上经过的黑点数不超过 k 个。
Analysis:
点分治 + 动态规划)
。。。有待分析。
const int MOD = 1000000007;
const int INF = 0x7fffffff;
const int N = 200000 + 9, M = N * 2;
int a[M], b[M], w[M], prd[M], suc[M]; // edge ..
int dist[N], max_dep[N], dep[N], sz[N], hd[N]; bool isBlack[N]; // vertx ..
int L[N], Ln, F[N], Fn, G[N], Gn; // core ..
int n, n_, m, k, _c, c, ans;
inline void remove(int x){
if (x == hd[a[x]]) prd[hd[a[x]] = suc[x]] = 0;
else suc[prd[suc[x]] = prd[x]] = suc[x];
}
#define v b[i]
inline void dfs1(int u, int p){
max_dep[u] = dep[u];
if (!p){
for(int i=hd[u];i;i=suc[i]){
remove(i^1), dist[v] = dist[u] + w[i], dep[v] = dep[u] + isBlack[v];
dfs1(v, u), checkMax(max_dep[u], max_dep[v]), L[Ln++] = v;
}
}
else {
for(int i=hd[u];i;i=suc[i]) if (v != p){
dist[v] = dist[u] + w[i], dep[v] = dep[u] + isBlack[v];
dfs1(v, u), checkMax(max_dep[u], max_dep[v]);
}
}
}
inline void dfs2(int u, int p){
if (dep[u] >= Gn) return;
checkMax(G[dep[u]], dist[u]);
for(int i=hd[u];i;i=suc[i]) if (v != p){
dfs2(v, u);
}
}
inline void find_center(int u, int p){
int blc = 0; sz[u] = 1;
for(int i=hd[u];i;i=suc[i]) if (v != p){
find_center(v, u), sz[u] += sz[v];
checkMax(blc, sz[v]);
}
checkMax(blc, n_ - sz[u]);
if (blc <= _c) _c = blc, c = u;
}
inline bool shller(int a, int b){
return max_dep[a] < max_dep[b];
}
inline void stat(bool rt){
if (!rt || k){
sort(L, L+Ln, shller); Fn = 1; REP(i, Ln){
Gn = min(max_dep[L[i]] + 1, k + !rt), dfs2(L[i], 0);
FOR(j, 1, Gn) checkMax(G[j], G[j-1]);
FOR(j, 0, Fn) {
int t = k - j - rt;
checkMax(ans, F[j] + (t<Gn?G[t]:G[Gn-1]));
}
checkMax(Fn, Gn); REP(j, Fn) checkMax(F[j], G[j]);
//REP(i, Gn) G[i] = 0;
fill(G, G+Gn, 0);
}
//REP(i, Fn) F[i] = 0;
fill(F, F+Fn, 0);
}
Ln = 0;
}
inline void solve(int u = 1){
_c = INF, find_center(u, 0), u = c;
dep[u] = dist[u] = 0, dfs1(u, 0),
stat(isBlack[u]);
for(int i=hd[u];i;i=suc[i]){
n_ = sz[v], solve(v);
}
}
int main(){
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
//ios::sync_with_stdio(false);
RD(n, k, m); DO(m) isBlack[RD()] = true;
for (int i=2;i<n<<1;++i){
RD(a[i], b[i]); RD_S(w[i]), a[i|1] = b[i], b[i|1] = a[i], w[i|1] = w[i];
prd[hd[a[i]]] = i, suc[i] = hd[a[i]], hd[a[i]] = i; ++i;
prd[hd[a[i]]] = i, suc[i] = hd[a[i]], hd[a[i]] = i;
}
n_ = n, solve(), printf("%d\n", ans);
}




Alca
Amber
Belleve Invis
Chensiting123
Edward_mj
Fotile96
Hlworld
Kuangbin
Liyaos
Lwins
LYPenny
Mato 完整版
Mikeni2006
Mzry
Nagatsuki
Neko13
Oneplus
Rukata
Seter
Sevenkplus
Sevenzero
Shirleycrow
Vfleaking
wangzhpp
Watashi
WJMZBMR
Wywcgs
XadillaX
Yangzhe
三途川玉子
About.me
Vijos
