【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即可,f(i,j)表示前i个数,划分成j段的最优值。
只有三种决策,要么不取,继承f(i-1,j),要么将其自己作为某段的最小值,转移自f(i-1,j-1),要么将其与其前位的lca作为某段的最小值,转移自f(i-2,j-1)。
如果用tarjan预处理相邻的lca的话,复杂度是O(n*K)。
比std不知道高明到哪里去了。234ms。
UPDATE: 靠,换成动态求lca以后,明明多了一个log,变成140ms了。
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef pair<int,int> Point;
vector<vector<int> >f;
vector<Point>ask[300005];
int a[300005],head[300005],to[600005],nxt[600005],lca[300005];
int n,k,u,v,en;
void add(int u,int v)
{
nxt[++en]=head[u];
head[u]=en;
to[en]=v;
}
int FA[300005],ans[300005],dep[300005];
bool VIS[300005];
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+1);
int f1=find(u),f2=find(to[i]);
FA[f1]=f2;
ans[find(u)]=u;
}
VIS[u]=true;
for(int i=0;i<ask[u].size();i++)
if(VIS[ask[u][i].first]){
lca[ask[u][i].second]=ans[find(ask[u][i].first)];
}
}
int main()
{
while(scanf("%d%d",&n,&k)!=EOF)
{
f.assign(n+1,vector<int>(k+1,0));
memset(VIS,0,sizeof(VIS));
for(int i=1;i<=n;++i){
ask[i].clear();
FA[i]=i;
}
en=0;
for(int i=1;i<=n;++i)
{
scanf("%d",&a[i]);
}
for(int i=2;i<=n;++i){
ask[a[i-1]].push_back(make_pair(a[i],i));
ask[a[i]].push_back(make_pair(a[i-1],i));
}
for(int i=1;i<n;++i)
{
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
LCA(1,1);
for(int i=2;i<=n;++i)
lca[i]=dep[lca[i]];
for(int i=1;i<=n;++i)
{
int top=min(i,k);
for(int j=0;j<=top;++j)
{
int nowans=99999999;
if(j>0&&i>0)
nowans=min(nowans,f[i-1][j-1]+dep[a[i]]);
if(i-2>=0&&j-1>=0&&j-1<=i-2)
nowans=min(nowans,f[i-2][j-1]+lca[i]);
if(j<=i-1)
nowans=min(nowans,f[i-1][j]);
f[i][j]=nowans;
}
}
printf("%d\n",f[n][k]);
for(int i=1;i<=n;++i)
{
dep[i]=0;
head[i]=0;
}
}
return 0;
}
【Tarjan】【LCA】【动态规划】【推导】hdu6065 RXD, tree and sequence的更多相关文章
- 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 ...
- RXD, tree and sequence IN HDU6065
解这道题绕了好多弯路...先是把"depth of the least common ancestor"这句话忽视掉,以为是最深点与最浅点的深度差:看到某人题解(的开头)之后发现自 ...
- 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 ...
- 【BZOJ4784】[ZJOI2017]仙人掌(Tarjan,动态规划)
[BZOJ4784][ZJOI2017]仙人掌(Tarjan,动态规划) 题面 BZOJ 洛谷 题解 显然如果原图不是仙人掌就无解. 如果原图是仙人掌,显然就是把环上的边给去掉,变成若干森林连边成为仙 ...
- 【BZOJ1093】[ZJOI2007]最大半联通子图(Tarjan,动态规划)
[BZOJ1093][ZJOI2007]最大半联通子图(Tarjan,动态规划) 题面 BZOJ 洛谷 洛谷的讨论里面有一个好看得多的题面 题解 显然强连通分量对于题目是没有任何影响的,直接缩点就好了 ...
- Tarjan+LCA【洛谷P2783】 有机化学之神偶尔会做作弊
[洛谷P2783] 有机化学之神偶尔会做作弊 题目背景 XS中学化学竞赛组教练是一个酷爱炉石的人. 有一天他一边搓炉石一边监考,而你作为一个信息竞赛的大神也来凑热闹. 然而你的化竞基友却向你求助了. ...
- poj 3417 Network(tarjan lca)
poj 3417 Network(tarjan lca) 先给出一棵无根树,然后下面再给出m条边,把这m条边连上,然后每次你能毁掉两条边,规定一条是树边,一条是新边,问有多少种方案能使树断裂. 我们设 ...
- 洛谷 P2783 有机化学之神偶尔会做作弊(Tarjan,LCA)
题目背景 LS中学化学竞赛组教练是一个酷爱炉石的人. 有一天他一边搓炉石一边监考,而你作为一个信息竞赛的大神也来凑热闹. 然而你的化竞基友却向你求助了. “第1354题怎么做”<--手语 他问道 ...
随机推荐
- document的属性与方法小结
document节点是文档的根节点,每张网页都有自己的document节点.属性:1:document.doctype----它是一个对象,包含了当前文档类型 (Document Type Decla ...
- Eclipse连接海马模拟器
找到海马模拟器安装目录: 使用cmd 命令进入命令行:D: cd:D:\Program Files (x86)\Droid4X 进入模拟器所在目录 运行adb connect 127.0.0.1:26 ...
- Mimikatz.ps1本地执行
PS C:\Users\hacker> Get-ExecutionPolicy Restricted PS C:\Users\hacker> Set-ExecutionPolicy Unr ...
- Port-knocking 简单教程
0. "port knocking" 如字面意思,类似'敲门',只是这里敲的是'端口',而且需要按照顺序'敲'端口.如果敲击规则匹配,则可以让防火墙实时更改策略.从而达到开关防火墙 ...
- DTW 算法(转)
DTW为(Dynamic Time Warping,动态时间归准)的简称.应用很广,主要是在模板匹配中,比如说用在孤立词语音识别,计算机视觉中的行为识别,信息检索等中.可能大家学过这些类似的课程都看到 ...
- windows7 能连接移动硬盘 无法显示盘符
右键点我的电脑,管理里,点磁盘管理,看盘认到没,有时候认到了但是没给盘符,需要自己手动给一个
- C 基础框架开发
引言 有的人真的是天命所归 延安时期炸弹 投到他院子都 没炸. 有些事无法改变 是命! 我们也快'老'了, 常回家看看. 前言 扯淡结束了,今天分享的可能有点多,都很简单,但是糅合在一起就是有点复杂. ...
- leetcode 之Valid Palindrome(26)
现在开始进入字符串系列. 判断回文串的.首尾各定义一个指针,然后相比较.难点在于如何提出非字母数字的字符. bool isValidPalind(string s) { //转为小写,注意这个函数的用 ...
- 修改VNCSERVER 默认的分辨率的方法
vi /usr/bin/vncserver /1024 找到默认的1024*768修改为 :1680*1050 reboot 重启
- C10问题
C10K问题是指服务器同时支持成千上万个客户端的问题,也就是concurrent 10 000 connection(这也是C0K这个名字的由来).由于硬件成本幅度降低和硬件版本的提高,如果服务器能够 ...