RXD, tree and sequence IN HDU6065
解这道题绕了好多弯路。。。先是把"depth of the least common ancestor"这句话忽视掉,以为是最深点与最浅点的深度差;看到某人题解(的开头)之后发现自己理解错误,修改思路。结果又是绕好多弯路。构造了一个式子dp[i,j]其中i是前几个点,j是切分的段数。一直以为转移是整段转移(如果段是(1,5),直接dp[5,j]=dp[0,j-1]+val(1,5)),但是发现时间复杂度又过高,o(nk*n),之后改变了下思路,发现这题的整段真正有用的是最小深度那个核。
题意是把一串n排列切分成k段,让里面的数计算这些对应结点的最近公共祖先深度,之后求这个最小深度总和。如(1) (5 2 4 3),第1段是1的深度,第2段是min( dep(lca(5,2)) , dep(lca(2,4)) , dep(lca(4,3)) ),其中的核就是最小的那个deplca。
dp转移不需转移整段,可以空转移,只要保证加上那个核的权值之后跳到下一段就行,这样转移步幅小了很多(1~2),dp次数也降为o(nk)
dp[i,j]=dp[i-1,j](把i这个点当成对答案无关的跳过)dp[i-1,j-1](把i这个点当成对答案有关的核转移)dp[i-2,j-1](把i-1和i的最近公共祖先当成对答案有关的核转移)
这里的代码很无耻地借鉴了autsky-jadek的。。。
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#define min(a,b) (a<b?a:b)
using namespace std;
typedef pair<int,int> Point;
const int N=;
int a[N],head[N],to[N<<],nxt[N<<],lca[N],fa[N],dep[N],ans[N],arc[N];
bool vis[N];
int n,k,u,v,en;
int dp[N+]; void addedge(int u,int v)
{
to[en]=v;
nxt[en]=head[u];
head[u]=en++;
}
int find_(int x){
return x==fa[x] ? x : fa[x]=find_(fa[x]);
}
void LCA(int u,int nowdeep)
{
ans[u]=u;
dep[u]=nowdeep;
for(int i=head[u];i!=-;i=nxt[i]) if(!dep[to[i]])
{
LCA(to[i],nowdeep+);
int f1=find_(u),f2=find_(to[i]);
fa[f1]=f2;
ans[find_(u)]=u;
}
vis[u]=true;
if(u!= && vis[u-])
lca[u-]=ans[find_(u-)];
if(u!=n- && vis[u+])
lca[u]=ans[find_(u+)];
}
int main()
{
int tmp,i;
while(scanf("%d%d",&n,&k)!=EOF)
{
en=;
memset(vis,,sizeof(vis));
memset(dep,,sizeof(dep));
memset(head,-,sizeof(head));
memset(dp,,sizeof(dp));
for(i=;i<n;i++)
{
scanf("%d",&tmp);
arc[tmp]=fa[i]=i;
}
for(i=;i<n;i++)
{
scanf("%d%d",&u,&v);
addedge(arc[u],arc[v]);addedge(arc[v],arc[u]);
}
LCA(arc[],);
for(i=;i<n-;++i)
lca[i]=dep[lca[i]];
for(i=;i<=n;++i)
{
int top=min(i,k);
for(int j=;j<=top;++j)
{
int nowans=;
if(j>&&i>)
nowans=min(nowans,dp[(i-)*(k+)+j-]+dep[i-]);
if(i->=&&j->=&&j-<=i-)
nowans=min(nowans,dp[(i-)*(k+)+j-]+lca[i-]);
if(j<=i-)
nowans=min(nowans,dp[(i-)*(k+)+j]);
dp[i*(k+)+j]=nowans;
}
}
printf("%d\n",dp[n*(k+)+k]);
}
return ;
}
tarjan离线,全局求祖先,顺带把相邻数字全查了
RXD, tree and sequence IN HDU6065的更多相关文章
- HDU 6065 RXD, tree and sequence (LCA DP)
RXD, tree and sequence Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java ...
- 【Tarjan】【LCA】【动态规划】【推导】hdu6065 RXD, tree and sequence
划分出来的每个区间的答案,其实就是连续两个的lca的最小值. 即5 2 3 4 这个区间的答案是min(dep(lca(5,2)),dep(lca(2,3),dep(lca(3,4)))). 于是dp ...
- HDU 6065 RXD, tree and sequence (LCA+DP)
题意:给定上一棵树和一个排列,然后问你把这个排列分成m个连续的部分,每个部分的大小的是两两相邻的LCA的最小深度,问你最小是多少. 析:首先这个肯定是DP,然后每个部分其实就是里面最小的那个LCA的深 ...
- hdu 6065 RXD, tree and sequence
题 OwO http://acm.hdu.edu.cn/showproblem.php?pid=6065 (2017 Multi-University Training Contest - Team ...
- ※数据结构※→☆非线性结构(tree)☆============二叉树 顺序存储结构(tree binary sequence)(十九)
二叉树 在计算机科学中,二叉树是每个结点最多有两个子树的有序树.通常子树的根被称作“左子树”(left subtree)和“右子树”(right subtree).二叉树常被用作二叉查找树和二叉堆或是 ...
- Java基础之泛型——使用二叉树进行排序(TryBinaryTree)
控制台程序. 1.实现针对容器类的基于集合的循环 为了让容器类类型的对象能够在基于集合的for循环中可用,类必须并且只需要满足一个要求——必须实现泛型接口java.lang.Iterable<& ...
- (04)odoo视图操作
-----------------更新时间19:04 2016-09-29 星期四11:17 2016-09-18 星期日18:13 2016-04-05 星期二15:05 2016-03-14 星期 ...
- awesome-nlp
awesome-nlp A curated list of resources dedicated to Natural Language Processing Maintainers - Keon ...
- 二叉树的Morris遍历
二叉树的遍历,除了上篇文章中的传统递归和使用的栈结构的非递归方式,还有如下这种Morris遍历方式,该算法的构思非常巧妙:利用前驱空闲的rightChild指针指向当前节点,形成一个环.时间复杂度和前 ...
随机推荐
- 七、Sql Server 基础培训《进度7-笛卡尔积(知识点+实际操作)》
知识点: 1.笛卡尔介绍 笛卡尔,近代法国著名哲学家.物理学家.数学家.神学家. 主要成就概述 笛卡尔在科学上的贡献是多方面的.笛卡尔不仅在哲学领域里开辟了一条新的道路,同时笛卡尔又是一勇于探索的科学 ...
- HBuilder控制台集成命令提示符(终端/CMD)功能
参考:https://jingyan.baidu.com/album/6b97984dc9cda31ca2b0bf00.html?picindex=3
- Educational Codeforces Round 1
598A - Tricky Sum 20171103$$ans=\frac{n(n+1)}{2} - 2\sum_{k=0}^{\left \lfloor \log_2 n \right \rf ...
- 远程连接ubuntu mysql出现2003错误 cant connect to mysql(转载)
不多说直接上代码 1.在控制台输入,进入mysql目录下, sudo su //进入root权限 cd /etc/mysql 2.打开my.cnf文件,找到 bind-address = 127.0. ...
- 15.vue动画& vuex
Vue.config.productionTip = false; ==是否显示提示信息== ==import/export== export xxx 必须跟跟对象或者和定义一起 对象: export ...
- Listen error 错误和 limit of inotify watches was reached
今天在生产环境中报错rails c中报了一个错误: FATAL: Listen error: unable to monitor directories for changes. Visit http ...
- 剑指offer——python【第28题】数组 中出现次数超过一半的数字
题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...
- css的小知识
---恢复内容开始--- 1.当你发现在制作页面时出现滚动条就需要一个去除滚动条的属性 overflow:hidden: overflow-x:hidden:水平超出隐藏 2. ...
- shell 脚本的编写
创建一个shell文件 1. 创建一个.sh文件 2. 文件第一行声明shell编译器路径 #!/bin/bash 3. 修改文件权限 chmod 777 文件名 或 /bin/bash ...
- HDU 1010生成树
求起点到终点的最短权值和