描述
给定一棵含有 n 个结点的树,结点从 1 标号。你从 1 号结点驾车出发,希望遍历一些关键结点(访问到就好,不需要按照这些关键结点的输入顺序)。每条边有两个权值,c0, c1 分别表示步行和驾车经过这条边的代价。每次你可以选择驾车经过一条边(当且仅当有车),或者将车停放在当前所在的结点(如果有车),步行经过一条边。
求遍历完所有关键结点的最少代价。
注意: 你可以在任意结点结束遍历,即使当前没有车。

解题报告:
用时:2h20min,1RE1WA
这题做的不是很好,首先看到题目思考了许久找不到好一点的状态,然后参考了题解的状态
\(f[x][0/1/2/3/4]\)表示x子树内所有的关键点都已经走完的5中状态的最小代价
\(f[x][0]\)表示只考虑人走,且人必须回到x的最小代价
\(f[x][1]\)表示只考虑人走,且人可以不回来的最小代价(用于f[x][4]的转移)
\(f[x][2]\)表示人车一起走,且两者都回来的最小代价
\(f[x][3]\)表示人车一起走,且人回车不回的最小代价(用于f[x][4]的转移)
\(f[x][4]\)表示人车一起走,最后两者都不回来的最小代价
在自己做的时候并没有定义到\(f[x][3]\)这个状态,然后发现\(f[x][4]\)是可以借助\(f[x][3]\)转移的

设\(dis\)为该边人走的代价,\(dis0\)为车走的代价,\(u\)为x的子节点
\(f[x][0]=\sum_{u}f[u][0]+2*dis\)
\(f[x][2]=\sum_{u}Min(f[u][2]+2*dis0,f[u][0]+2*dis)\)
这两个比较显然,对于\(f[x][2]\)你可以带着车一起走完回来,也可以把车放在原地,走完回来
设\(t=(f[u][2]+2*dis0,f[u][0]+2*dis)\)
\(f[x][1]\)就是某一个子节点走的是\(f[u][1]+dis\),其他节点走的是\(t\)
\(f[x][3]\)同理,某一个点走\(f[u][3]+dis+dis0\),其他点走\(t\)
显然这两个节点的特殊节点的选择都是选择贡献最大的,即\(f[u][1]+dis\)和\(f[u][0]+dis*2\)做差后最大的一个
对于\(f[x][4]\)两者都不回,我们要分情况讨论:
1.在遍历最后一颗子树时,有车
显然遍历之前是\(f[x][3]\),然后可以选择最后一颗子树是开车还是不开车对应\(f[u][1]\)和\(f[u][4]\)
2.若此时没有车
遍历之前状态是\(f[x][2]\),其中某个子树是\(f[u][3]\),表示车没有回来人回来了,然后和上面一种情况不同的是:只能选择人走了,那么就是在不同于选择了\(f[u][3]\)的子树中再选择一个走\(f[v][1]\)
一个我没注意到的细节:
如果u同于v,那么应该记录一个次小值,不然就会少一组转移

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const int N=1e6+5;
int head[N],num=0,to[N<<1],nxt[N<<1],dis[N<<1],dis0[N<<1];
void link(int x,int y,int d,int d0){nxt[++num]=head[x];to[num]=y;dis[num]=d;dis0[num]=d0;head[x]=num;
}
int gi(){int str=0;char ch=getchar();while(ch>'9' || ch<'0')ch=getchar();while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();return str;
}
int n,m;bool vis[N],mark[N];ll f[N][5];
void dfs(int x,int last){int u,imp;ll t,f1=0,f2=0,f3=0,tmp,f4=0;mark[x]=vis[x];for(int i=head[x];i;i=nxt[i]){u=to[i];if(u==last)continue;dfs(u,x);mark[x]+=mark[u];if(!mark[u])continue;f[x][0]+=f[u][0]+(dis[i]<<1);t=Min(f[u][2]+(dis0[i]<<1),f[u][0]+(dis[i]<<1));f[x][2]+=t;f1=Min(f1,f[u][1]-f[u][0]-dis[i]);tmp=f[u][3]+dis[i]+dis0[i]-t;if(tmp<f2){f4=f2;f2=tmp;imp=u;}else if(tmp<f4)f4=tmp;f3=Min(f3,min(f[u][4]+dis0[i],f[u][1]+dis[i])-t);}f[x][1]=f[x][0]+f1;f[x][3]=f[x][2]+f2;f[x][4]=f[x][2]+f3;f[x][4]=Min(f[x][4],f[x][3]);for(int i=head[x];i;i=nxt[i]){u=to[i];if(u==last || !mark[u])continue;t=Min(f[u][2]+(dis0[i]<<1),f[u][0]+(dis[i]<<1));tmp=f[u][1]+dis[i]-t;if(u==imp)f[x][4]=Min(f[x][4],f[x][2]+tmp+f4);else f[x][4]=Min(f[x][4],f[x][2]+tmp+f2);}
}
void work()
{int x,y,d,d0;n=gi();for(int i=1;i<n;i++){x=gi();y=gi();d=gi();d0=gi();link(x,y,d,d0);link(y,x,d,d0);}m=gi();for(int i=1;i<=m;i++){x=gi();vis[x]=true;}dfs(1,1);printf("%lld\n",Min(f[1][4],f[1][0]));
}int main()
{work();return 0;
}

转载于:https://www.cnblogs.com/Yuzao/p/7527289.html

hihocoder 1035 : 自驾旅行 III相关推荐

  1. 一个人长途自驾旅行需要注意什么?

    自我亲身体验,一个人长途自驾旅行需要注意的是:吃好,喝好,玩好,休息好,把车开好!下面听我细细道来. 1.吃好喝好 民以食为天,自古以来,吃好喝好,是第一位的.有了吃喝作为身体保障,才能做好旅游,特别 ...

  2. [hihocoder 1075] 开锁魔法III

    题意:小朋友有N个盒子,每个盒子装着打开第ai个盒子的钥匙,小朋友一开始可以使用洪荒之力打开k个盒子,求他能开完所有盒子的概率 题解: DP+组合数 首先几个盒子通过多次打开一定会形成一个环,设每个环 ...

  3. hihocoder 1075 : 开锁魔法III

    描述 一日,崔克茜来到小马镇表演魔法. 其中有一个节目是开锁咒:舞台上有 n 个盒子,每个盒子中有一把钥匙,对于每个盒子而言有且仅有一把钥匙能打开它.初始时,崔克茜将会随机地选择 k 个盒子用魔法将它 ...

  4. 缤客发布2021年可持续旅行报告;爱彼迎全球招募12人体验“旅居四方” | 全球旅报...

    Booking.com缤客发布2021年可持续旅行报告.这项针对全球30个国家和地区,逾2.9万名旅行者开展的研究,近八成(79%)中国旅客认为人们应当采取行动,减少旅游活动对环境可能产生的威胁.Bo ...

  5. 【观影】摩托日记、盲井

    最近看了两部片子 摩托日记,讲切·格瓦拉年轻时候的自驾旅行的,我是很好奇会不会拍的像咱们的<青年***>一样. 看下来感觉还不错,前面的部分两个人的浪荡生活,想起了当初背包时自由的感觉.好 ...

  6. ado filter 多条记录_车里能开直播 行车记录仪十大隐藏设置

    [爱卡汽车 用车 原创] 相信大家都知道行车记录仪的功能就是实时记录画面,在发生交通事故或者遇到碰瓷的时候可以提供视频证据.不过往往有些朋友只知道行车记录仪这个功能,其实除了这些,还可以激活行车记录仪 ...

  7. 在顺丰的历史上,扩大规模的资金来源

    在顺丰的历史上,扩大规模的资金来源要么是银行贷款,要么是企业经营所得.2004年起,王卫先后9次将物业或商铺抵押给银行.不过,快递是典型的轻资产行业,在银行看来,如果跑去车辆和地皮,快递公司拥有的网点 ...

  8. 「亚马逊先生」的出世与入世

    编译 | 王宇欣 程耀彤 张震 白悦 邱陆陆 作者 | N. Wingfield; N. Bowles 来源 | New York Times 上周末,Jeff Bezos 和 Halle Berry ...

  9. 组合数学-排列组合整理

    此文是我整理组合数学排列组合知识的博文,排列组合从零开始...加油! 1.重复组合: 从n种不同元素中取出m的元素(方法是从n个元素中每次取出一个后,放回,再取另外一个,直到取出m个元素),每一种元素 ...

最新文章

  1. 田野中科院计算机网络信息中心,中国科学院
  2. 环境调试: RuntimeWarning: Couldn‘t find ffmpeg or avconv - defaulting to ffmpeg, but may not work warn(“
  3. linux tar cvf_Linux中的Tar命令:Tar CVF和Tar XVF通过示例命令进行了解释
  4. leetcode -- Single Number
  5. 数字电子技术基础(六):译码器、数据选择器
  6. IAR for MSP430安装教程
  7. 优化算法(一)SGD算法实现
  8. 人工智能 - 电子书下载(高清版PDF格式+EPUB格式)
  9. sklearn机器学习(七)决策树预测泰坦尼克号幸存者
  10. python爬虫学习之路(二)re库的使用方法
  11. java中各种O的含义(PO,DO,VO,TO,QO,BO,DAO,DTO,POJO)
  12. 牛客网 赛码网 js输入输出
  13. minecraft_适用于Linux的Minecraft故事模式,Alienware的Steam机器以及更多开放式游戏新闻
  14. 汉字转拼音函数 linux,汉字转拼音占内存更少转换速度更快的程序
  15. 数据库设计之物理结构设计
  16. 文件创建时间、修改时间、访问时间的定义
  17. UI设计中首页设计指南
  18. 《内网安全攻防:渗透测试实战指南》读书笔记(四):权限提升分析及防御
  19. 电阻、电感、电容、电子元件认识
  20. Windows 10 1909升级2004

热门文章

  1. 提高国内访问 GitHub 的速度的方案
  2. Nacos笔记-对Nacos初步认识
  3. 信息安全工程师笔记-案例分析(二)
  4. IDA笔记-IDA Pro基本使用
  5. C++工作笔记-调试release版的dll
  6. 网站建设:部署与发布
  7. 2021广西蒙山中学高考成绩查询,广西省蒙山中学2020-2021学年高二下学第一次月考数学(文)试题及答案.doc...
  8. cmake 安装mysql5.6_使用cmake在CentOS6.5安装MYSQL5.6
  9. 事务失败返回_什么是分布式事务以及有哪些解决方案?
  10. c语言实现语音检测vad_TWS+AI?国芯发布超低功耗语音芯片,可能是目前最理想方案...