树上游戏..二合一?

题目描述

曾经发明了零件组装机的发明家 SHTSC 又公开了他的新发明:聚变反应炉——一种可以产生大量清洁能量的神秘装置。

众所周知,利用核聚变产生的能量有两个难点:一是控制核聚变反应的反应强度,二是使用较少的能量激发聚变反应。而 SHTSC 已经完美解决了第一个问题。一个聚变反应炉由若干个相连的聚变块组成,为了能够使得聚变反应可控,SHTSC 保证任意两个聚能块都可以通过相互之间的链接到达,并且没有一个聚能块可以不重复经过一个链接回到它自己。

但是第二个问题 SHTSC 还没有完全解决。在他设计的聚变反应炉当中,每个聚变块都需要一定的初始能量 \(d_i\) 来进行激发,不过 SHTSC 不需要手动激发所有聚变块,这是因为一旦一个聚变块被激发,则会向与其直接相连的所有还未被激发的聚变块传送 \(c_i\) 个单位的能量。这样后被触发的聚变块可以以更低的初始能量来激发,甚至可能不需要额外的外界能量就可自行激发,从而降低了总激发能量的消耗。现在给出了一个聚变反应炉,求至少要多少能量才能激发所有聚变块。

输入输出格式

输入格式:

第一行一个整数 \(n\),表示共有 \(n\) 个聚能块,由 \(1\) 至 \(n\) 编号。

第二行 \(n\) 个整数,依次表示 \(d_i\)​。

第三行 \(n\) 个整数,依次表示 \(c_i\)​。

以下 \(n-1\) 行每行两个整数 \(u,v\),表示编号为 \(u\) 和 \(v\) 的聚能块是相连的。

输出格式:

一行一个整数,表示至少需要多少个单位的能量才能激发所有聚变块。

输入输出样例

输入样例:

5
1 1 1 1 1
1 1 1 1 1
1 2
2 3
3 4
4 5

样例输出:

1

样例解释:

只需要触发任意一个聚变块即可激活整个聚变反应装置。

数据范围与约定

Case # \(\max\{c_i\}\) \(n\) 附加限制
1 \(=1\) \(\leq 10\) \(c_i = 1\)
2 \(=1\) \(\leq 100\) \(c_i = 1\)
3 \(=1\) \(\leq 200\) \(c_i = 1\)
4 \(=0\) \(\leq 10\) -
5 \(=1\) \(\leq 200\) \(c_i = 1\)
6 \(=1\) \(\leq 200\) -
7 \(=1\) \(\leq 100000\) \(c_i = 1\)
8 \(=0\) \(\leq 100000\) -
9 \(=1\) \(\leq 100000\) -
10 \(=1\) \(\leq 100000\) -
11 \(\leq 5\) \(\leq 20\) -
12 \(\leq 5\) \(\leq 20\) \(c_i\) 均相等
13 \(\leq 5\) \(\leq 200\) -
14 \(\leq 5\) \(\leq 200\) \(c_i\) 均相等
15 \(\leq 5\) \(\leq 200\) -
16 \(\leq 5\) \(\leq 200\) -
17 \(\leq 5\) \(\leq 2000\) \(c_i\) 均相等
18 \(\leq 5\) \(\leq 2000\) -
19 \(\leq 5\) \(\leq 2000\) -
20 \(\leq 5\) \(\leq 2000\) -

题解:

前面50分是个贪心。只需要先激发所有的 \(1\) 再激发所有的 \(0\) 即可。

此时考虑 \(1\) 之间会不会互相影响。因为相邻的 \(1\) 所造成的影响只是先后顺序上的,早晚都会减掉的,只是位置不同而已。

后面50分需要高阶树形dp,实则是个背包。用 \(f[i][j]\) 表示 \(i\) 号点在已接受儿子们贡献的 \(j\) 点能量后的最小花费,要把 \(j\) 当成背包那一维。

并且有可能出现 \(j>d_i\) 的情况,但是这是不合法的。因此我们也需要控制,当接收的能量超过 \(d_i\) 时要按 \(d_i\) 算。

此外,对于每个儿子做背包的时候,如果不接受它贡献的能量,则可以自己贡献能量给它。所以dp转移方程并不像以前的背包那样,而是要计算能量下传可能带来的更小代价。

因此我们做到一个儿子 \(v\) 的时候,先求出给它下传能量后的最小代价 \(m=\min\{f[v][j]-\min(c_i,d_v-j)\}\),然后dp的时候再利用这个值就可以了。

因此转移方程为(正在转移儿子 \(v\))

\[f[i][j]=\left\{\begin{matrix}
f[i][0]+m&j=0,\\\
\min(f[i][j-c_v]-c_v+F[v],f[i][j]+m)&k\le j\le d_i\\\
\min_{0\le k\le c_v}\{f[i][d_i-k]-k+F[v]\}&j=d_i
\end{matrix}\right.
\]

其中 \(F[v]=\min_{0}^{d[v]}\{f[v][i]\}\)。

加 \(F[v]\) 的是从儿子获取能量,涉及 \(m\) 的是自己下传能量。

不过从儿子获取的能量最多为 \(nc_i\) ,为10000,因此数组只用开 10000 即可,注意边界问题。

Code:

#include<cstdio>
#include<cstring>
int Min(int x,int y){return x<y?x:y;}
struct edge
{
int n,nxt;
edge(int n,int nxt)
{
this->n=n;
this->nxt=nxt;
}
edge(){}
}e[200100];
int head[100100],ecnt=-1;
void add(int from,int to)
{
e[++ecnt]=edge(to,head[from]);
head[from]=ecnt;
e[++ecnt]=edge(from,head[to]);
head[to]=ecnt;
}
int d[100100],c[100100];
int F[2010];
void dfs(int x,int from)
{
int f[10010];
memset(f,0x3f,sizeof(f));
f[x][0]=d[x];
for(int i=head[x];~i;i=e[i].nxt)
if(e[i].n!=from)
{
dfs(e[i].n,x);
int k=c[e[i].n],tmp=0x3fffffff,t=F[e[i].n]; for(int j=0;j<=10000;++j)
{
f[x][j]+=t;
tmp=Min(tmp,f[e[i].n][j]-Min(c[x],d[e[i].n]-j));
} //对于每个物品 拿或不拿都有不同的贡献 需要注意 if(d[x]<=10000)
{
f[x][d[x]]-=t-tmp;
for(int j=d[x];j>=d[x]-k;--j)
f[x][d[x]]=Min(f[x][d[x]],f[x][j]-(d[x]-j));
} for(int j=Min(d[x]-1,10000);j>=k;--j)
f[x][j]=Min(f[x][j]-t+tmp,f[x][j-k]-k); if(k)
{
f[x][0]-=F[e[i].n];//撤销统一修改
f[x][0]+=tmp;
} }
for(int i=0;i<=10000;++i)
if(f[x][i]<F[x])
F[x]=f[x][i];
}
int main()
{
memset(f,0x3f,sizeof(f));
memset(F,0x3f,sizeof(F));
memset(head,-1,sizeof(head));
int n,u,v;
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%d",&d[i]);
for(int i=1;i<=n;++i)
scanf("%d",&c[i]);
for(int i=1;i<n;++i)
{
scanf("%d%d",&u,&v);
add(u,v);
}
if(n>2000)//数据分治
{
for(int i=1;i<=n;++i)
if(c[i])
for(int j=head[i];~j;j=e[j].nxt)
if(e[j].n>i||!c[e[j].n])
--d[e[j].n];
int sum=0;
for(int i=1;i<=n;++i)
sum+=d[i]<0?0:d[i];
printf("%d\n",sum);
return 0;
}
dfs(1,1);
printf("%d\n",F[1]);
return 0;
}

洛谷 P4269 / loj 2041 [SHOI2015] 聚变反应炉 题解【贪心】【DP】的更多相关文章

  1. 洛谷 P4774 / loj 2721 [NOI2018] 屠龙勇士 题解【同余】【exgcd】【CRT】

    推导过程存在漏洞+exCRT板子没打熟于是期望得分÷实际得分=∞? 题目描述 小 D 最近在网上发现了一款小游戏.游戏的规则如下: 游戏的目标是按照编号 \(1\sim n​\) 顺序杀掉 \(n​\ ...

  2. 洛谷 P3239 / loj 2112 [HNOI2015] 亚瑟王 题解【期望】【DP】

    ???看不懂的期望DP 题目描述 小 K 不慎被 LL 邪教洗脑了,洗脑程度深到他甚至想要从亚瑟王邪教中脱坑. 他决定,在脱坑之前,最后再来打一盘亚瑟王.既然是最后一战,就一定要打得漂亮.众所周知,亚 ...

  3. 洛谷 P4108 / loj 2119 [HEOI2015] 公约数数列 题解【分块】

    看样子分块题应该做的还不够. 题目描述 设计一个数据结构. 给定一个正整数数列 \(a_0, a_1, \ldots , a_{n-1}\),你需要支持以下两种操作: MODIFY id x: 将 \ ...

  4. 洛谷【P2458】[SDOI2006]保安站岗 题解 树上DP

    题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下超市的所有通道呈一棵树的形状:某些通道之间可以互 ...

  5. 【洛谷5008】逛庭院(Tarjan,贪心)

    [洛谷5008]逛庭院(Tarjan,贪心) 题面 洛谷 题解 如果图是一个\(DAG\),我们可以任意选择若干个不是入度为\(0\)的点,然后把它们按照拓扑序倒序删掉,不难证明这样一定是合法的. 现 ...

  6. 洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心)

    洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/132 ...

  7. [Noi2016]区间 BZOJ4653 洛谷P1712 Loj#2086

    额... 首先,看到这道题,第一想法就是二分答案+线段树... 兴高采烈的认为我一定能AC,之后发现n是500000... nlog^2=80%,亲测可过... 由于答案是求满足题意的最大长度-最小长 ...

  8. BZOJ5291/洛谷P4458/LOJ#2512 [Bjoi2018]链上二次求和 线段树

    原文链接http://www.cnblogs.com/zhouzhendong/p/9031130.html 题目传送门 - LOJ#2512 题目传送门 - 洛谷P4458 题目传送门 - BZOJ ...

  9. 洛谷P4501/loj#2529 [ZJOI2018]胖(ST表+二分)

    题面 传送门(loj) 传送门(洛谷) 题解 我们对于每一个与宫殿相连的点,分别计算它会作为多少个点的最短路的起点 若该点为\(u\),对于某个点\(p\)来说,如果\(d=|p-u|\),且在\([ ...

随机推荐

  1. SQL数据库游标

    这个文档几乎包含了oracle游标使用的方方面面,全部通过了测试 -- 声明游标:CURSOR cursor_name IS select_statement --For 循环游标--(1)定义游标- ...

  2. Hyperledger Fabric Ordering Service过程

    排序服务在超级账本 Fabric 网络中起到十分核心的作用.所有交易在发送给 Committer 进行验证接受之前,需要先经过排序服务进行全局排序. 在目前架构中,排序服务的功能被抽取出来,作为单独的 ...

  3. Linux、Windows中的相对路径和绝对路径

    获取系统的分隔符的方式:System.getProperty("file.separator")   Windows为 \   Linux为/ Windows绝对路径: 以盘符开始 ...

  4. .html与.text的异同

    .html与.text的方法操作是一样,只是在具体针对处理对象不同 .html处理的是元素内容,.text处理的是文本内容 .html只能使用在HTML文档中,.text 在XML 和 HTML 文档 ...

  5. 使用Monkey对APP进行随机测试

    Monkey测试简介 Monkey测试是Android平台自动化测试的一种手段,通过Monkey程序模拟用户触摸屏幕.滑动Trackball.按键等操作来对设备上的程序进行压力测试,检测程序多久的时间 ...

  6. Head First Python之2函数模块

    模块就是一个包含Python代码的文本文件,以.py结尾. 第三方模块都在PyPI(python package index)上,可使用PyPI发布你的模块,供他人使用. 注释代码 # coding= ...

  7. LibreOJ 6001 太空飞行计划(最大流)

    题解:首先源点向每个实验建边,流量为经费的值,实验向器材建边,值为无限大,器材向终点建边,值为价值 然后跑一遍最大流就能跑出所谓的最大闭合图的点值之和. 代码如下: #include<queue ...

  8. 操作系统下spinlock锁解析、模拟及损耗分析

    关于spinlock 我们在知道什么是spinlock之前,还需要知道为什么需要这个spinlock?spinlock本质就是锁,提到锁,我们就回到了多线程编程的混沌初期,为了实现多线程编程,操作系统 ...

  9. 死磕Java之聊聊ArrayList源码(基于JDK1.8)

    工作快一年了,近期打算研究一下JDK的源码,也就因此有了死磕java系列 ArrayList 是一个数组队列,相当于动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractLis ...

  10. http服务 WCF、Web API、Web service、WCF REST之间的区别

      http服务 WCF.Web API.Web service.WCF REST之间的区别 在.net平台下,有大量的技术让你创建一个HTTP服务,像Web Service,WCF,现在又出了Web ...