[CF1073F]Choosing Two Paths
题目大意:有一棵树,从中选取$2$条链,其中任何一条链的端点不能被另一条链包含,求这两条链,使这两条链的公共的点的部分最长,若相同,使得总长度最长。
题解:树形$DP$,因为端点互不包含,所以公共的部分的端点一定有两个及以上的儿子,然后可以把这样的点先全部求出来。求新树的直径就可以满足第一个要求(洛谷题意有锅,没有写在相同情况下要求总长度最长,导致我最后重构代码)。
那如何使得相同情况下总长度最长呢?可以再维护一个以$i$为根的子树内以$i$为一个端点的最长链和次长链,$DP$时以新树的深度为第一关键字,以最长链和次长链长度总和为第二关键字就可以了。
卡点:1.题意错误
2.按最长链和次长链长度总和比较时比较的是转移的两点,而不是两个端点
C++ Code:
#include <cstdio>
#define maxn 200010
inline int max(int a, int b) {return a > b ? a : b;}
int head[maxn], cnt;
struct Edge {
int to, nxt;
} e[maxn << 1];
inline void add(int a, int b) {
e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;
}
bool choose[maxn];
int ind[maxn];
int n, root;
struct node {
int P, M;
inline node() {}
inline node(int __P, int __M) {M = __M, P = __P;}
inline node operator + (const int &rhs) const {return node(P, M + rhs);}
inline friend operator < (const node &lhs, const node &rhs) {return lhs.M < rhs.M;}
} V[maxn][2];
void dfs(int u, int fa = 0) {
if (ind[u] > 1) choose[u] = true;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (v != fa) {
dfs(v, u);
if (ind[u] == 2 && !choose[v]) choose[u] = false;
}
}
}
int f[maxn], F[maxn];
node dfs1(int u, int fa = 0) {
V[u][0] = node(u, 0); V[u][1] = node(0, 0);
f[F[u] = u] = choose[u];
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (v != fa) {
node tmp = dfs1(v, u) + 1;
if (f[v] + choose[u] > f[u]) {
f[u] = f[v] + choose[u];
F[u] = F[v];
} else if (f[v] + choose[u] == f[u]) {
if (choose[v] && V[F[u]][1].M + V[F[u]][0].M <= V[F[v]][1].M + V[F[v]][0].M) {
F[u] = F[v];
}
}
if (V[u][0] < tmp) {
V[u][1] = V[u][0];
V[u][0] = tmp;
} else if (V[u][1] < tmp) V[u][1] = tmp;
}
}
return V[u][0];
}
int main() {
scanf("%d", &n);
for (int i = 1, a, b; i < n; i++) {
scanf("%d%d", &a, &b);
add(a, b);
add(b, a);
ind[a]++, ind[b]++;
if (ind[a] >= 3) root = a;
if (ind[b] >= 3) root = b;
}
dfs(root);
int x, a, b, c, d;
dfs1(root);
x = F[root], a = V[F[root]][0].P, c = V[F[root]][1].P;
dfs1(x);
b = V[F[x]][0].P, d = V[F[x]][1].P;
printf("%d %d\n%d %d\n", a, b, c, d);
return 0;
}

浙公网安备 33010602011771号