Parade

Parade

官方题解(英文)

就是求树上,使得与路径相邻但是不在路径上的边的数量最大化的路径。

可以把路径分成两类,一是一直向根的方向走的路径,二是先往上走,然后又往下走的。按这个分类,用树上DP来求:

可以看到(DiD_i是节点ii的度):

然后对所有点求最大值就可以了。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
 
int n;      // 2e5
vector<int> adj[200005];
int dp[200005][2];
 
bool isLeaf(int s) {
    return s != 0 && adj[s].size() == 1;
}
 
void dfs(int s, int e) {
    int outdeg = adj[s].size();
    int first = 0, second = 0;
    for (int u: adj[s]) {
        if (u == e) continue;
        dfs(u, s);
        int v = max(dp[u][0], (int)adj[u].size());
        dp[s][0] = max(dp[s][0], v + outdeg - 2);
        if (v >= first) {
            second = first;
            first = v;
        } else second = max(second, v);
    }
    if (s == 0 && outdeg == 2 || outdeg >= 3)
        dp[s][1] = first + second - 2 + (outdeg - 2);
}
 
int main() {
    scanf("%d", &n);
    for (int i = 0; i < n-1; i++) {
        int u,v;
        scanf("%d %d", &u, &v);
        u--,v--;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(0, -1);
    int ans = 0;
    for (int i = 0; i < n; i++)
        if (i == 0 || adj[i].size() > 1)   // non-leaf
            ans = max(ans, max(dp[i][0], dp[i][1]));
    printf("%d", ans);
 
    return 0;
}