4585: [Apio2016]烟火表演

Time Limit: 40 Sec  Memory Limit: 256 MB
Submit: 115  Solved: 79
[Submit][Status][Discuss]

Description

烟花表演是最引人注目的节日活动之一。在表演中,所有的烟花必须同时爆炸。为了确保安
全,烟花被安置在远离开关的位置上,通过一些导火索与开关相连。导火索的连接方式形成
一棵树,烟花是树叶,如[图1]所示。火花从开关出发,沿导火索移动。每当火花抵达一个分
叉点时,它会扩散到与之相连的所有导火索,继续燃烧。导火索燃烧的速度是一个固定常
数。[图1]展示了六枚烟花{E1,E2...E6 }的连线布局,以及每根导火索的长度。图中还标
注了当在时刻 从开关点燃火花时,每一发烟花的爆炸时间。
Hyunmin为烟花表演设计了导火索的连线布局。不幸的是,在他设计的布局中,烟花不一定
同时爆炸。我们希望修改一些导火索的长度,让所有烟花在同一时刻爆炸。例如,为了让[图
1]中的所有烟花在时刻 13爆炸,我们可以像[图2]中左边那样调整导火索长度。类似地,为
了让[图1]中的所有烟花在时刻 14爆炸,我们可以像[图2]中右边那样调整长度。
修改导火索长度的代价等于修改前后长度之差的绝对值。例如,将[图1]中布局修改为[图2]
左边布局的总代价为6 ,而将[图1]中布局修改为[图2]右边布局的总代价为 5.
导火索的长度可以被减为0 ,同时保持连通性不变。
给定一个导火索的连线布局,你需要编写一个程序,去调整导火索长度,让所有的烟花在同
一时刻爆炸,并使得代价最小。
 

Input

所有的输入均为正整数。令 N代表分叉点的数量, M代表烟花的数量。分叉点从1 到N 编

号,编号为1 的分叉点是开关。烟花从N+1 到 N+M编号。1<=N+M<=300,000
输入格式如下:
N M
P2 C2
P3 C3
...
Pn Cn
PN+1 CN+1
...
PN+m CN+M
其中Pi 满足 1<=Pi<i,代表和分叉点或烟花i 相连的分叉点。 Ci代表连接它们的导火索长
度( 1<=Ci<=10^9)。除开关外,每个分叉点和多于1 条导火索相连,而每发烟花恰好与 1条导
火索相连。

Output

输出调整导火索长度,让所有烟花同时爆炸,所需要的最小代价

Sample Input

4 6
1 5
2 5
2 8
3 3
3 2
3 3
2 9
4 4
4 3

Sample Output

5
 
这个题解很妙啊....
估计我扯不清....干脆就放个有点注释的代码吧。
#include<cstdio>

typedef long long ll;
const int len(),N();
int n,m,fa[len+]; ll sum,C[len+];
int max(int a,int b){return a>b?a:b;}
template<class T>void read(T &x)
{
x=;bool f=;char c=getchar();
while((c<''||c>'')&&c!='-')c=getchar();if(c=='-')f=,c=getchar();
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
x=f?-x:x;
}
struct Leftist{ll val;int dis,nx[];}Lheap[N<<];int tot,root[N],son[N];
void swap(int &x,int &y){if(x==y)return;x^=y;y^=x;x^=y;}
int merge(int x,int y)
{
if(!x||!y)return x|y;
if(Lheap[x].val<Lheap[y].val)swap(x,y);
Lheap[x].nx[]=merge(Lheap[x].nx[],y);
if(Lheap[Lheap[x].nx[]].dis<Lheap[Lheap[x].nx[]].dis)swap(Lheap[x].nx[],Lheap[x].nx[]);
Lheap[x].dis=Lheap[Lheap[x].nx[]].dis+;
return x;
}
//int slope(int x){return son[x]-Lheap[root[x]].size+1;}//返回x所在堆顶元素的斜率,好像错了
void pop(int x)
{
if(!x)return;
root[x]=merge(Lheap[root[x]].nx[],Lheap[root[x]].nx[]);
}
void deal(int x,int y,int w)//处理x的儿子y,其边长w
{
while(--son[y])pop(y);
//等价于:while(slope(y)>0&&Lheap[root[y]].size)pop(y);
//有son[y]个斜率大于等于0,最后一个等于0
ll R=Lheap[root[y]].val; pop(y);
ll L=Lheap[root[y]].val; pop(y);
Lheap[++tot]=(Leftist){L+w,,,};
root[y]=merge(root[y],tot);
Lheap[++tot]=(Leftist){R+w,,,};
root[y]=merge(root[y],tot);
root[x]=merge(root[x],root[y]);
}
int main()
{
// freopen("C.in","r",stdin);
read(n),read(m);
for(int i=;i<=n+m;i++) read(fa[i]),read(C[i]),sum+=C[i];
// fprintf(stderr,"1\n");
for(int i=n+m;i>=;i--)
{
if(i>n)
{
Lheap[++tot]=(Leftist){C[i],,,};
root[fa[i]]=merge(root[fa[i]],tot);
Lheap[++tot]=(Leftist){C[i],,,};
root[fa[i]]=merge(root[fa[i]],tot);//L=R
}else deal(fa[i],i,C[i]);
son[fa[i]]++;
// fprintf(stderr,"%d \n",i);
}
while(son[]--)pop();//等于0没贡献
int tp=;
for(tp=;root[];tp++)
C[tp]=Lheap[root[]].val,pop();
for(int i=tp-;i>=;i--)//不好算初始斜率,但知道k(i+1)=k(i)+1,(C[i]-C[i+1])*k(i)+(C[i-1]-C[i])*k(i+1)....
//C(tp)不算,C(tp)即最左边的拐点是按道理是0,但是因为上面是没有平移,只有相对间距,所以就忽略C(tp)。
sum-=C[i];
printf("%lld\n",sum);
return ;
}

UOJ #205/BZOJ 4585 【APIO2016】Fireworks 可并堆+凸包优化Dp的更多相关文章

  1. bzoj 4585: [Apio2016]烟火表演【左偏树】

    参考:https://blog.csdn.net/wxh010910/article/details/55806735 以下课件,可并堆部分写的左偏树 #include<iostream> ...

  2. UOJ#7. 【NOI2014】购票 | 线段树 凸包优化DP

    题目链接 UOJ #7 题解 首先这一定是DP!可以写出: \[f[i] = \min_{ancestor\ j} \{f[j] + (d[j] - d[i]) * p[i] + q[i]\}\] 其 ...

  3. CF372C Watching Fireworks is Fun(单调队列优化DP)

    A festival will be held in a town's main street. There are n sections in the main street. The sectio ...

  4. BZOJ 1010 玩具装箱toy(四边形不等式优化DP)(HNOI 2008)

    Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1... ...

  5. bzoj 1911 [Apio2010]特别行动队(斜率优化+DP)

    1911: [Apio2010]特别行动队 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 3191  Solved: 1450[Submit][Statu ...

  6. BZOJ 1492: [NOI2007]货币兑换Cash [CDQ分治 斜率优化DP]

    传送门 题意:不想写... 扔链接就跑 好吧我回来了 首先发现每次兑换一定是全部兑换,因为你兑换说明有利可图,是为了后面的某一天两种卷的汇率差别明显而兑换 那么一定拿全利啊,一定比多天的组合好 $f[ ...

  7. bzoj 2131 : 免费的馅饼 (树状数组优化dp)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2131 思路: 题目给出了每个馅饼的下落时间t,和位置p,以及价值v,我们可以得到如下状态 ...

  8. BZOJ 1010: [HNOI2008]玩具装箱toy(斜率优化dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1010 题意: 思路: 容易得到朴素的递归方程:$dp(i)=min(dp(i),dp(k)+(i-k ...

  9. BZOJ 3963 HDU3842 [WF2011]MachineWorks cdq分治 斜率优化 dp

    http://acm.hdu.edu.cn/showproblem.php?pid=3842 写的check函数里写的<但是应该是<=,调了一下午,我是个zz. 就是普通的斜率优化因为有两 ...

随机推荐

  1. vb常用命名空间

    摘自:http://www.2cto.com/kf/201211/170837.html 感谢 (一)如下是系统中分离出来Imports MicrosoftImports Microsoft.CSha ...

  2. FZU - 2218 Simple String Problem(状压dp)

    Simple String Problem Recently, you have found your interest in string theory. Here is an interestin ...

  3. Mac下安装rJava,xlsx,ReporteRs包

    xlsx包可以用来读取excel数据,ReporteRs包可以用来直接输出word报告,这两个包都对rJava包有依赖,所以必须先安装rJava. (1)查看mac的java信息 java版本: &g ...

  4. 洛谷P3763 [TJOI2017]DNA(后缀自动机)

    传送门 好像用SAM写的很少诶…… 其实我一开始也没想到要用SAM的……主要是没有想到找的时候可以dfs…… 首先建一个SAM,然后跑一遍dfs,枚举一下下一位,如果相同直接继续,否则就花费一次次数来 ...

  5. IT兄弟连 Java语法教程 编写Java源代码

    现在我们来一步一步的编写第一个Java程序,鼎鼎大名的“HelloWorld”. 编写Java源代码 编写Java源代码可以使用任何无格式的文本编辑器,在Windows操作系统上可以使用记事本.Edi ...

  6. Laravel Model 利用 Macroable 为数据模型添加宏能力

    什么是ThinkSNS ? ThinkSNS(简称TS),一款全平台综合性社交系统,为国内外大中小企业和创业者提供社会化软件研发及技术解决方案,目前最新版本为ThinkSNS+(简称TS+).Thin ...

  7. 调试接口,返回的json数据,我定义了一个类,用来序列化,其中有一个字段定义为string 然后序列化的时候报错

    调试接口,返回的json数据,我定义了一个类,用来序列化,其中有一个字段定义为string 然后序列化的时候报错 在需要解析的类型类上加上声明 eg:

  8. [題解](函數下整點個數?)luogu_P4132_BZOJ_2659_算不出的等式

    兩個都是一次函數,下取整就是整點個數,兩個函數k剛好成倒數,所以最後發現會組合成一個矩形 (為啥要考慮重複與否的問題???) 然而這樣會不會重複計算點數呢 我們發現因為取的是圖像下的整數點 所以要想重 ...

  9. 【手撸一个ORM】第二步、封装实体描述和实体属性描述

    一.实体属性描述 [MyProperty.cs] Name,属性名称 PropertyInfo,反射获取的属性信息,后面很多地方需要通过该属性获取对应的实体类型,或调用SetValue进行赋值 Fie ...

  10. NET Core 2.1 Global Tools

    微软工程师Nate McMaster的博文.NET Core 2.1 Global Tools https://natemcmaster.com/blog/2018/05/12/dotnet-glob ...