题目链接:https://codeforces.com/contest/1293/problem/E

题目大意:

  给出一棵树,要求给树的每条边赋权值,使得树中所有点的 m e x ( x , y ) mex(x,y) mex(x,y)和最大,并输出这个和
   m e x ( x , y ) mex(x,y) mex(x,y)指的是从x到y的路径中,没出现过的整数的最小值

题目思路:

  推荐qsc的题解视频:传送门
  很容易发现,在这个条件下,一定要有人做出牺牲,也就是只有一条链上能够从小到大接连着,还可以发现的是,只要有一条边选择了0,那么这条边两头的点满足 m e x ( x , y ) ≥ 1 mex(x,y)\ge1 mex(x,y)≥1,因为他们中最小的整数为0,也就是对于这样的一条连着的整数链来说,比如0,1,2,这样的链两边的点形成的链值至少为3,这也就是这道题的精髓。
  可以发现,这题n只有3000,所以支持n^2,那么就很美滋滋,刚才发现,从小到大接着的链非常重要,所以直接 n 2 n^2 n2枚举这条链。首先需要一个预处理, f a [ r o o t ] [ u ] fa[root][u] fa[root][u]表示以root为根,u的父亲是谁, n u m [ r o o t ] [ u ] num[root][u] num[root][u]表示以root为根,以u为顶点的子树有多少点。然后使用 d p [ x ] [ y ] dp[x][y] dp[x][y]来表示x,y为链的情况下的最大值是多少。如何dp呢?假设求1-2-3-4这样的链的结果,那么假如我们已经知道了它的子结果,1-2-3和2-3-4的结果,我们要从这个结果推出1-2-3-4结果,那么根据我们的分析,从1-2-3和2-3-4变成1-2-3-4都是加上1-2-3-4这条链两头点的乘积(就是这棵树中有多少条链能够覆盖这条链,他们都能得到这个加成),既然加的数值一样,那么肯定选他们两个中大的那个啦。数量的话很简单,对于x-…-y这条链来说,x那边的点的个数就是以y为根,x为子树顶点的子树的点数量,另一边就正好相反,就是刚才说的 n u m [ r o o t ] [ u ] num[root][u] num[root][u]可以得到,而1-2-3和2-3-4的获得,就可以用 f a [ r o o t ] [ u ] fa[root][u] fa[root][u],同样对于x-…-y这条链来说, f a [ x ] [ y ] fa[x][y] fa[x][y]就是x-…-y这条链中,与y直接相连的那个点。
  感觉这题非常巧妙,有很多可以学习的点,是一个好题。感觉讲的已经比较清楚,代码也比较剪短可以结合代码学习。如果还有有问题的地方欢迎评论区提出一起讨论~

以下是代码:

#include<bits/stdc++.h>using namespace std;
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define inf 0x3f3f3f3f
const int MAXN = 3e3+5;
vector<int>v[MAXN];
ll fa[MAXN][MAXN],num[MAXN][MAXN],dp[MAXN][MAXN],root;
void dfs(int u,int f){num[root][u]=1;int len=v[u].size();rep(i,0,len-1){int y=v[u][i];if(y==f)continue;fa[root][y]=u;dfs(y,u);num[root][u]+=num[root][y];}
}
ll solve(int x,int y){if(x==y)return 0;if(dp[x][y])return dp[x][y];return dp[x][y]=num[x][y]*num[y][x]+max(solve(x,fa[x][y]),solve(y,fa[y][x]));
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);int n,x,y;while(cin>>n){rep(i,1,n)v[i].clear();memset(fa,0,sizeof(fa));memset(num,0,sizeof(num));memset(dp,0,sizeof(dp));rep(i,1,n-1){cin>>x>>y;v[x].push_back(y);v[y].push_back(x);}rep(i,1,n){root=i;dfs(i,-1);}ll ans=0;rep(i,1,n){rep(j,i+1,n){ans=max(ans,solve(i,j));}}cout<<ans<<endl;}return 0;
}

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

  1. Codeforces Round #614 (Div. 1) C.Xenon's Attack on the Gangs(树形dp)

    题目 给你一棵n(n<=3000)个点的树,树上每个点对(u,v)对答案的贡献是mex(u,v), mex就是sg函数里的那个mex 每个点对只被统计一次,令所有点对的贡献和最大,输出贡献和 思 ...

  2. Codeforces Round #637 (Div. 2) - Thanks, Ivan Belonogov! D. Nastya and Scoreboard题解(记忆化搜索)

    题目链接 题目大意 一个n个数码位的分数板,每一个数码位都是一个七段数码管,现在给出每个数码位的显示情况,问再点亮k段数码管的话能显示的最大的数是多少,如果不能构成一串数字,就输出-1.答案允许有前导 ...

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

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

  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. 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 ...

  6. Codeforces Round #699 (Div. 2) F - AB Tree(贪心、树上DP)超级清晰,良心题解,看不懂来打我 ~

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Codeforces Round #699 (Div. 2) F - AB Tree Problem ...

  7. 【Christmas Game】【CodeCraft-21 and Codeforces Round #711 (Div. 2)】【Nim-博弈】【树形DP】【拆分树】

    CodeCraft-21 and Codeforces Round #711 (Div. 2) Christmas Game Nim-博弈 树形DP 拆分树 牛客链接 https://ac.nowco ...

  8. Codeforces Round #614 (Div. 2) D. Aroma‘s Search 暴力 + 思维

    传送门 文章目录 题意: 思路: 题意: 给你x0,y0,ax,ay,bx,byx_0,y_0,a_x,a_y,b_x,b_yx0​,y0​,ax​,ay​,bx​,by​,让后根据[ax∗xi−1+ ...

  9. Codeforces Round #594 (Div. 2) Ivan the Fool and the Probability Theory(DP)

    题目链接:https://codeforces.com/contest/1248/problem/C 题目大意:n*m的长方形中,一共有两种颜色,问每一个块相邻最多有一个与之相同颜色的块的染色方案数 ...

最新文章

  1. 鸟哥的Linux私房菜(基础篇)-第二章、 Linux 如何学习(二.4. 鸟哥的建议(重点在solution的学习))
  2. wxWidgets:wxHelpEvent类用法
  3. 阿里云能耗宝新品发布
  4. Concurrent集合 Atomic类
  5. 【完全开源】微信客户端.NET版
  6. python数学表达式3+(a+b)2_python3的基础学习之数学(2)
  7. 快速排序 java导包_排序算法-快速排序(Java实现)
  8. SpringBoot—JPA: javax.persistence.TransactionRequiredException
  9. Django-Model操作数据库(增删改查、连表结构)
  10. c# winform 打印 窗体 及 窗体控件内容 的 初级尝试
  11. 计算机网络常用术语WWW,计算机网络常用术语
  12. 反编译那些事儿(四)—序列化问题
  13. 结对编程项目-四则运算 第二周
  14. 实例讲解遗传算法——基于遗传算法的自动组卷系统【实践篇】
  15. linux虚拟磁带机管理,linux虚拟磁带机
  16. linux可运行的steam游戏吗,Steam现在可以在Linux上玩仅Windows游戏
  17. python xgboost建模过程_python - Dask中的XGBoost建模 - SO中文参考 - www.soinside.com
  18. Matlab App Designer 【04】使用公共函数在两个App之间传递数据
  19. c语言入门:比较三个数的大小
  20. 从0开始学Unity做SLG系列(发布篇)

热门文章

  1. HTML创建表格及合并单元格
  2. 基于iPhone 上的运动协处理器M7判断用户当前的运动(姿态)类型
  3. 解读广告SDK工作机制,保护App自身安全
  4. 经营报表-FineReport配置Oracle外接数据库(2)
  5. Excel 快速计算相邻行之间的时间差
  6. JAVAWEB增删改查武林秘籍
  7. 一个程序员心态决定成败
  8. 别人可以在今日头条发文章赚钱,为什么你赚不到呢?
  9. python居然还能画出这么精美的魔法少女,惊我一整年
  10. KMP算法的时间复杂度