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;
}
posted @ 2020-11-19 21:57  lahlah  阅读(27)  评论(0编辑  收藏  举报