正题

题目链接:https://www.luogu.com.cn/problem/P7276?contestId=39577


题目大意

\(n\)个点的一棵树,\(k\)个关键点,两个人从根出发分别走一段路径回到根。要求每个关键点至少被一个人经过,求最短时间。


解题思路

相当于求两个覆盖所有关键点的联通子图,使得最大那棵最小。

树上只留下关键点和它们的祖先节点,这样就变为了所有点都要经过,也就是所有叶子都要经过。

然后比较显然的结论是一定会按照\(dfs\)从小到大的顺序走,所以可以直接\(dp\)。设\(f_{i,j,k}\)表示两个人分别走到\(i,j\),目前第二棵树的大小为\(k\)时第一棵树的最小大小。

注意转移\(x->i\)的时候权值得是\(dis(\ LCA(x,i),i\ )\),因为是联通子图上延伸下来一条路径。

时间复杂度\(O(n^3)\)

因为是比赛的时候写的代码改的,所以比较丑。


code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=420;
struct node{
int to,next;
}a[N<<1];
int n,k,tot,num,ls[N],dep[N],f[N],lca[N][N],ans,dp[N][N][N],son[N];
bool mark[N];
void addl(int x,int y){
a[++tot].to=y;
a[tot].next=ls[x];
ls[x]=tot;return;
}
bool calc(int x,int fa){
dep[x]=dep[fa]+1;
for(int i=ls[x];i;i=a[i].next){
int y=a[i].to;
if(y==fa)continue;
f[y]=x;mark[x]|=calc(y,x);
}
return mark[x];
}
void dfs(int x,int fa){
if(!mark[x])return;
bool flag=1;
for(int i=ls[x];i;i=a[i].next){
int y=a[i].to;
if(y==fa||!mark[y])continue;
flag=0;break;
}
if(flag||x==1)son[++num]=x;
for(int i=ls[x];i;i=a[i].next){
int y=a[i].to;
if(y==fa)continue;
dfs(y,x);
}
return;
}
int LCA(int x,int y){
while(dep[x]>dep[y])x=f[x];
while(dep[y]>dep[x])y=f[y];
while(x!=y)x=f[x],y=f[y];
return x;
}
int dis(int x,int y)
{return dep[y]-dep[lca[x][y]];}
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
addl(x,y);addl(y,x);
}
for(int i=1;i<=k;i++){
int x;scanf("%d",&x);
mark[x]=1;
}
calc(1,1);dfs(1,1);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
lca[i][j]=LCA(i,j);
memset(dp,0x3f,sizeof(dp));
ans=dp[1][1][0];dp[1][1][0]=0;son[++num]=1;
for(int i=2;i<=num;i++)
for(int x=1;x<i;x++)
for(int y=1;y<i;y++){
if(x!=i-1&&y!=i-1)continue;
for(int z=0;z<n;z++){
int d=dis(son[x],son[i]);
dp[i][y][z]=min(dp[i][y][z],dp[x][y][z]+d);
d=dis(son[y],son[i]);
if(z>=d)dp[x][i][z]=min(dp[x][i][z],dp[x][y][z-d]);
}
}
for(int i=0;i<=num;i++)
for(int j=0;j<=num;j++){
if(i!=num&&j!=num)continue;
for(int z=0;z<n;z++)
ans=min(ans,max(dp[i][j][z],z));
}
printf("%d\n",ans*2);
}

P7276-送给好友的礼物【dp】的更多相关文章

  1. hpuoj--校赛--送给新生的礼物(水题)

    问题 A: 感恩节KK专场--送给新生的礼物 时间限制: 1 Sec  内存限制: 128 MB 提交: 631  解决: 187 [提交][状态][讨论版] 题目描述 学长KK要送给学弟学妹们礼物, ...

  2. 【Codeforces 506E】Mr.Kitayuta’s Gift&&【BZOJ 4214】黄昏下的礼物 dp转有限状态自动机+矩阵乘法优化

    神题……胡乱讲述一下思维过程……首先,读懂题.然后,转化问题为构造一个长度为|T|+n的字符串,使其内含有T这个子序列.之后,想到一个简单的dp.由于是回文串,我们就增量构造半个回文串,设f(i,j, ...

  3. Python3实现QQ机器人自动爬取百度文库的搜索结果并发送给好友(主要是爬虫)

    一.效果如下: 二.运行环境: win10系统:python3:PyCharm 三.QQ机器人用的是qqbot模块 用pip安装命令是: pip install qqbot (前提需要有request ...

  4. NSURLSession 网络库 - 原生系统送给我们的礼物

    大家在进行iOS开发的时候一定会用到网络操作.但由于早期原生的 NSURLConnection 操作起来有很多不便,使得大家更愿意使用第三方库的解决方案,比如鼎鼎大名的 AFNetworking.正是 ...

  5. 【COGS1049】天空中的繁星

    [题目背景] 第二届『Citric』杯NOIP提高组模拟赛 第二题 [题目描述] Lemon最近买了一台数码相机.某天Lemon很无聊,于是对着夜空拍了一张照片,然后把照片导入了电脑.Lemon想依靠 ...

  6. 皮裤原理和运营微信公众号dotNET跨平台

    经常碰到有同学对.NET跨平台存在各种疑惑和误解,原因是什么呢?当然我是知道.NET的跨平台不是问题,而且微软2014年的努力可圈可点,而且还有很多人对.NET的前景感到困惑.春节期间突然明白了,这就 ...

  7. K米点歌APP评测

    K米APP评测 产品简介 K米点歌是一款免费的社交K歌手机应用,其手机点歌功能主要在KTV.夜总会,酒吧等K歌场所中使用,当前提供iPhone版本及安卓版本下载使用.——百度百科 评测版本 K米点歌4 ...

  8. C#知识体系(二)用案例来理解委托与事件

    上一篇博客讲到了LinQ和lambda的常用方法 还有很多我们未知但c#设计团队已经为我们封装好的类和方法.随着我们不断的熟悉C#语言,渐渐的就会接触到其他的知识点,委托.事件.反射.线程.同步,异步 ...

  9. "2013":爱你不容易

    2013对我来说确实像年初时曾给自己定义的那样,真的是非常不平常的一年.依稀记得去年年终时,BOSS和我深聊了1多钟头,谈到职业规划.人生还有家庭的林林种种.春节在家时也仔细考虑过2013自己该如何规 ...

随机推荐

  1. React性能优化总结

    本文主要对在React应用中可以采用的一些性能优化方式做一下总结整理 前言 目的 目前在工作中,大量的项目都是使用react来进行开展的,了解掌握下react的性能优化对项目的体验和可维护性都有很大的 ...

  2. The Programmer's Oath程序员的誓言----鲍勃·马丁大叔(Bob Martin)

    In order to defend and preserve the honor of the profession of computer programmers, I Promise that, ...

  3. Spring PropertyPlaceholderConfigurer 自定义扩展

    原文地址:https://blog.csdn.net/feiyu8607/article/details/8282893 Spring中PropertyPlaceholderConfigurer这个类 ...

  4. ObjectInputStream和ObjectOutputStream

    package stream.object; import java.io.FileInputStream; import java.io.FileOutputStream; import java. ...

  5. 一招解决下载或下拉GitHub项目速度太慢的问题

    相信很多朋友都有过这样的体验,就是从Github上下载或clone别人的项目时特别慢,甚至还会出现链接意外终止的情况,那么今天就来给大家分享一个提速的方法,步骤也非常简单,亲测有效! 首先进入你的目标 ...

  6. 工具库用久了,你还会原生操作 Cookie 吗?

    用得好了,工具库和框架确实是一大助力,但就怕我们会因此习惯了走捷径,而忘了自己的根本依靠是什么. 前言 前端技术的飞速发展,给从业人员不可避免地带来了"疲劳"感,我们常常会感叹学不 ...

  7. redis内存回收

    1.定时过期expilre expire key TTL 10定时器 主动淘汰 2.惰性过期 被动淘汰 3getCommand expireIfNeed() 设置内存上线 set memory 上线 ...

  8. php ltrim() rtrim() trim()删除字符空格

    php$str=" 去除前后空格 ";echo "方括号中为原始字符串:[".$str."]";echo "原始字符串长度:&qu ...

  9. Python3-sqlalchemy-orm 分组统计

    #-*-coding:utf-8-*- #__author__ = "logan.xu" import sqlalchemy from sqlalchemy import crea ...

  10. 【MIT6.S081/6.828】手把手教你搭建开发环境

    目录 1. 简介 2. 安装ubuntu20.04 3. 更换源 3.1 更换/etc/apt/sources.list文件里的源 3.2 备份源列表 3.3 打开sources.list文件修改 3 ...