CF1292C Xenon‘s Attack on the Gangs
https://www.luogu.com.cn/problem/CF1292C
考虑从小到大放数
发现只有一条链的会产生贡献(放的数会连成一条链)
然后DP即可
#include<bits/stdc++.h>
#define N 4005
#define ll long long
using namespace std;
struct edge {
int nxt, v;
} e[N << 1];
int p[N], eid;
void init() {
memset(p, -1, sizeof p);
eid = 0;
}
void insert(int u, int v) {
e[eid].v = v;
e[eid].nxt = p[u];
p[u] = eid ++;
}
int size[N][N], fa[N][N], n;
ll f[N][N];
void dfs(int u, int rt) {
size[rt][u] = 1;
for(int i = p[u]; i + 1; i = e[i].nxt) {
int v = e[i].v;
if(v == fa[rt][u]) continue;
fa[rt][v] = u;
dfs(v, rt); size[rt][u] += size[rt][v];
}
}
ll dp(int u, int v) {// printf("%d %d\n", u, v);
if(u == v) return 0;
if(f[u][v]) return f[u][v];
return f[u][v] = max(dp(u, fa[u][v]), dp(v, fa[v][u])) + 1ll * size[u][v] * size[v][u];
}
int main() {
init();
scanf("%d", &n);
for(int i = 1; i < n; i ++) {
int u, v;
scanf("%d%d", &u, &v);
insert(u, v);
insert(v, u);
}
for(int i = 1; i <= n; i ++) dfs(i, i);
ll ans = 0;
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= n; j ++)
ans = max(ans, dp(i, j));
printf("%lld", ans);
return 0;
}