设 s z r o o t ( u ) sz_{root}(u) szroot​(u)表示以 r o o t root root为根,子树 T ( u ) T(u) T(u)的大小, f a r o o t ( u ) fa_{root}(u) faroot​(u)表示以 r o o t root root为根,节点 u u u的父亲。这两个东西可以 O ( n 2 ) O(n^2) O(n2)预处理。

转化一下问题:
a n s = ∑ x = 1 n − 1 ∑ u , v ∈ V [ m e x ( u , v ) ≥ x ] ans=\sum\limits_{x = 1}^{n - 1} \sum\limits_{u,v \in V} [\mathrm{mex}(u,v) \ge x] ans=x=1∑n−1​u,v∈V∑​[mex(u,v)≥x]
那么现在考虑从小到大加入每一个边权,首先加入边权 0 0 0:

那么一定可以得到 s z u ( v ) × s z v ( u ) sz_{u}(v) \times sz_{v}(u) szu​(v)×szv​(u)的贡献。那么接下来加入权值 1 1 1。

假如说 0 , 1 0,1 0,1不是连着的,那么两条边夹着的所有点对答案的就只能是 0 0 0,(如图)

接着想想,将 0 , 1 0,1 0,1连在一起有利无害,那么就连在一起吧。。。这启示我们,接下来放边权的时候,一定是尽量将之前已经放了边权形成的路径延长一个位置(这个想法比较古怪)。也就是说,对于 m e x \mathrm{mex} mex最长的一条路径,它所包含的边权可以组成 [ 0 , 路 径 长 度 − 1 ] [0,路径长度-1] [0,路径长度−1]这一个区间的,而且区间的两个端点一定在叶子上。接下来设定一条最长的路径 ( u , v ) (u,v) (u,v),我们想想怎么在上面填边权。首先在某个位置填上 0 0 0,然后任选左右其中位置填上 1 1 1,然后再选左右其中一个填上 2 2 2。每次填上一个边权之后,在答案中加入路径两边连着的子树的大小。这不就是 d p dp dp吗?设 f ( u , v ) f(u,v) f(u,v)表示形成了路径 ( u , v ) (u,v) (u,v)得到的最大 a n s ans ans。

那么可以得到:
f ( u , v ) = { max ⁡ { f ( f a v ( u ) , v ) , f ( u , f a u ( v ) } + s z u ( v ) × s z v ( u ) u ≠ v 0 u = v f(u,v)=\begin{cases} \max\left\{f(fa_{v}(u),v), f(u, fa_{u}(v)\right\} + sz_{u}(v)\times sz_{v}(u) & u \ne v\\ 0 & u = v \end{cases} f(u,v)={max{f(fav​(u),v),f(u,fau​(v)}+szu​(v)×szv​(u)0​u​=vu=v​

#include <bits/stdc++.h>
#define LL long longusing namespace std;const int maxn = 3e3 + 5;
struct Edge {int v, nex;Edge(int v = 0, int nex = 0) : v(v), nex(nex) {}
} E[maxn << 1];
int hd[maxn], tote;void addedge(int u, int v) {E[++tote] = Edge(v, hd[u]), hd[u] = tote;E[++tote] = Edge(u, hd[v]), hd[v] = tote;
} LL sz[maxn][maxn], fat[maxn][maxn], f[maxn][maxn];
int n, rt;void init(int u, int fa) {fat[rt][u] = fa, sz[rt][u] = 1;for (int i = hd[u]; i; i = E[i].nex) {int v = E[i].v;if (v == fa) continue;init(v, u), sz[rt][u] += sz[rt][v];}
}LL dp(int u, int v) {if (u == v) return 0;if (~f[u][v]) return f[u][v];return f[u][v] = max(dp(fat[v][u], v), dp(u, fat[u][v])) + sz[u][v] * sz[v][u];
}int main() {memset(f, -1, sizeof(f));scanf("%d", &n);for (int i = 1; i < n; i++) {int u, v; scanf("%d%d", &u, &v);addedge(u, v);}for (int i = 1; i <= n; i++) rt = i, init(i, 0);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\n", ans);return 0;
}

[题解][CF-1292C]Xenon‘s Attack on the Gangs相关推荐

  1. Codeforces 1292C Xenon's Attack on the Gangs

    题目链接 Codeforces 1292C Xenon's Attack on the Gangs 题目大意 给定一棵树,将 [ 0 , n − 2 ] [0,n-2] [0,n−2]内的每个整数都仅 ...

  2. CodeForces - 1292C Xenon‘s Attack on the Gangs(思维+dp)

    题目链接:点击这里 题目大意: 给出一颗有 n n n 个节点的数,将 [ 0 , n − 2 ] [0,n-2] [0,n−2] 内的每个整数各用一次分配到这颗树的 n − 1 n-1 n−1 条边 ...

  3. Xenon's Attack on the Gangs Codeforces Round #614 (Div. 2)

    Xenon's Attack on the Gangs 题意: 给你一棵树,将0~n-2一一赋值给n-1条边,则S最大可能取值 S = ∑ 1 ≤ u < v ≤ n m e x ( u , v ...

  4. E. Xenon's Attack on the Gangs,Codeforces Round #614 (Div. 2),树形dp

    E. Xenon's Attack on the Gangs http://codeforces.com/contest/1293/problem/E On another floor of the ...

  5. Codeforces Round #614 (Div. 2) E. Xenon's Attack on the Gangs(DP记忆化搜索+思维)

    题目链接:https://codeforces.com/contest/1293/problem/E 题目大意:   给出一棵树,要求给树的每条边赋权值,使得树中所有点的 m e x ( x , y ...

  6. Codeforces 1293 E. Xenon‘s Attack on the Gangs —— 树上记忆化搜索,单点加改成区间加,有丶东西

    This way 题意: 现在有一棵大小为n的树,你要往边上放0~n-2这n-1个数,定义mex(u,v)表示u到v路径上的第一个未出现的自然数,定义S 问你S最大是多少. 题解: 我感觉这道题绝不止 ...

  7. Xenon's Attack on the Gangs(树规)

    题干 Input Output Example Test 1: Test 2: 3 5 1 2 1 2 2 3 1 31 43 53 10 Tips 译成人话 给n个结点,n-1条无向边.即一棵树.我 ...

  8. codeforces1292C Xenon‘s Attack on the Gangs

    https://codeforces.com/problemset/status 这题一开始想着dfs贪心贪了好久,后来发现如果出现贡献相等的情况,不知道取那边扩展.花了很多时间才想出来,打cf的时候 ...

  9. [CF1292C] Xenon's Attack on the Gangs

    题意 题目链接 给定一棵树,试将 [ 0 , n − 2 ] [0,n-2] [0,n−2] 内的每个整数不重不漏填到每条边上,使得 ∑ 1 ≤ u < v ≤ n mex ( u , v ) ...

最新文章

  1. 大数据环境下该如何优雅地设计数据分层
  2. 根据值 加密后的值 算出key_Bugku:加密 rsa
  3. 开启报名丨中文信息学会青工委学术沙龙:“推荐系统前沿进展”
  4. CodeForces - 434D Nanami's Power Plant
  5. 介绍Pro*c编程的经验
  6. java logger使用_这才是JAVA中打印日志的正确姿势
  7. .NetCore 入门篇:理解
  8. 用计算机字符写名字,NSIS:把计算机名转换为大写或小写字符
  9. linux 开放端口
  10. java当中的定时器的4种使用方式
  11. 排序算法Java实现(希尔排序)
  12. 在 Mac 上的 Keynote 讲演中如何更改共享演示文稿的设置?
  13. 开发Windows物流管理系统——(二)代码实现
  14. 疯狂java讲义 如何_[java学习]《疯狂java讲义》
  15. opengl 3D平衡球小游戏
  16. YOLOX训练代码分析3-损失函数
  17. mysql 未找到 WinSxS_清理WinSxs释放 Win7 C盘所占的空间
  18. js和css动态画出一只安卓机器人,附代码
  19. 【力扣3题】快乐数有效的字母异位词字符串中的单词数
  20. Android获取手机屏幕像素大小

热门文章

  1. 简显易懂的TCP网络通信零起步(java网络画板,山寨腾讯会议)
  2. unity通过鼠标滑轮控制物体大小
  3. 华为机试 放苹果
  4. 吃鸡神器iPhone苹果7Plus手机基础使用教程
  5. UCenter单点登录,同步登录,同步登出原理
  6. 如何通过爱奇艺引流精准粉?
  7. 关于十七届恩智浦杯安徽赛区基础组参赛分享
  8. 机器学习----PyTorch入门
  9. 新生儿喝奶后不要马上放回床上睡觉,为宝宝健康着想,先做1件事
  10. pythonsocket接口_python socket 模块API