2013-09-15 20:04

题目描述

有这样一个游戏,桌面上摆了N枚硬币,分别标号1-N,每枚硬币有一个分数C[i]与一个后继硬币T[i]。作为游戏参与者的你,可以购买一个名为mlj的小机器人,从任一个硬币处开始游戏,然后跳往该硬币的后继硬币T[i],直到你要它停下来,经过每个硬币时,你可以选择是否捡起它。当某个mlj机器人停下来后将被扔掉,这时你可以选择结束游戏或再买一个mlj机器人继续游戏。

注意,每个硬币只能捡一次,而且你不能要求mlj跳向一个已被捡起的硬币或从一个已被捡起的硬币处开始游戏,因为那样会把mlj摔坏的。

Your Task

一开始你的得分是0,每购买一个mlj机器人将扣掉你M分,捡起一个硬币将得到对应的分数C[i],请问如何使得分尽量高(游戏过程中分数可以为负)。

输入文件

第一行两个正整数 N M

接下来N行,每行两个正整数C[i] T[i]。

输出文件

一个整数,最大得分。

样例输入

4 2

1 3

2 3

1 4

1 3

样例输出

2

数据约定

30%   N<=10

60%   N<=300

100   N<=100000  1<=T[i]<=N

运算过程及结果均在Longint范围内

因为有N个点,N条边,且每个点都只有一个后继,所以可推知图中一定存在环,所以先用tarjan缩点,得到一颗上宽下窄的树(因为一个点只能有一个后继,而每个点可以成为好多点的后继),为了DP方便,缩点重新建图时,将边反向,这时得到了一颗多叉树,考虑到可能出现森林,所以用一个总根节点将每颗多叉树的根节点连接起来。

然后我们得到了一颗多叉树,问题转化成了树形DP,由题意可知,因为到一个硬币可以不捡,所以机器人的路径可以重合,那么设W(X)代表从X节点向下走可以取得的最大值,假设X有多个儿子,因为当前有一个机器人由上方走来到X节点,所以X节点的儿子中最大的不用X重新买机器人,剩下的儿子中,如果W(P)>M,就相当于在P儿子处再买一个机器人,那么更新W(X)值,W(X):=W(P)-M;

{$m 500000000}
//By BLADEVIL
var
n, m :longint;
father :array[..] of longint;
start :longint;
flag, fseq :array[..] of boolean;
stack :array[..] of longint;
tot :longint;
time :longint;
low, dfn :array[..] of longint;
key :array[..] of longint;
color :longint;
pre, last, other :array[..] of longint;
l :longint;
mark :array[..] of longint;
ans :longint;
function min(a,b:longint):longint;
begin
if a>b then min:=b else min:=a;
end; procedure connect(x,y:longint);
begin
inc(l);
pre[l]:=last[x];
last[x]:=l;
other[l]:=y;
end; procedure dfs(x:longint);
var
cur :longint;
begin
inc(tot);
stack[tot]:=x;
flag[x]:=true;
fseq[x]:=true;
inc(time);
dfn[x]:=time;
low[x]:=time;
cur:=other[last[x]];
if not flag[cur] then
begin
dfs(cur);
low[x]:=min(low[x],low[cur]);
end else
if fseq[cur] then low[x]:=min(low[x],dfn[cur]); cur:=-;
if dfn[x]=low[x] then
begin
inc(color);
while cur<>x do
begin
cur:=stack[tot];
dec(tot);
fseq[cur]:=false;
key[cur]:=color;
mark[color]:=mark[color]+mark[cur];
end;
end;
end; procedure init;
var
i :longint;
x :longint;
p :longint;
begin
read(n,m); tot:=; color:=n;
for i:= to n do father[i]:=i;
for i:= to n do
begin
read(mark[i],x);
connect(i,x);
father[x]:=i;
end;
for i:= to n do if father[i]=i then start:=i;
if start= then inc(start);
dfs(start);
for i:= to n do if key[i]= then dfs(i); for i:= to n do
begin
p:=other[last[i]];
if key[i]<>key[p] then
begin
connect(key[p],key[i]);
father[key[i]]:=key[p];
end;
end;
for i:=n+ to color do if father[i]= then connect(color+,i); end; function w(x:longint):longint;
var
p, q :longint;
i, j, maxx :longint;
sum :longint;
begin
q:=last[x];
j:=;
w:=;
w:=w+mark[x];
maxx:=;
while q<> do
begin
p:=other[q];
sum:=w(p);
if sum>m then w:=w+sum-m;
if sum>maxx then maxx:=sum;
q:=pre[q];
end;
if maxx<m then w:=w+maxx else w:=w+m;
end; begin
assign(input,'coin.in'); reset(input);
assign(output,'coin.out'); rewrite(output);
init;
ans:=w(color+)-m;
if ans> then writeln(ans) else writeln();
close(input); close(output); end.

硬币问题 tarjan缩点+DP 莫涛的更多相关文章

  1. 【Codeforces】894E.Ralph and Mushrooms Tarjan缩点+DP

    题意 给定$n$个点$m$条边有向图及边权$w$,第$i$次经过一条边边权为$w-1-2.-..-i$,$w\ge 0$给定起点$s$问从起点出发最多能够得到权和,某条边可重复经过 有向图能够重复经过 ...

  2. BZOJ 1179 (Tarjan缩点+DP)

    题面 传送门 分析 由于一个点可以经过多次,显然每个环都会被走一遍. 考虑缩点,将每个强连通分量缩成一个点,点权为联通分量上的所有点之和 缩点后的图是一个有向无环图(DAG) 可拓扑排序,按照拓扑序进 ...

  3. Libre OJ 2255 (线段树优化建图+Tarjan缩点+DP)

    题面 传送门 分析 主体思路:若x能引爆y,从x向y连一条有向边,最后的答案就是从x出发能够到达的点的个数 首先我们发现一个炸弹可以波及到的范围一定是坐标轴上的一段连续区间 我们可以用二分查找求出炸弹 ...

  4. NOIP2009最优贸易[spfa变形|tarjan 缩点 DP]

    题目描述 C 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意两个 城市之间最多只有一条道路直接相连.这 m 条道路中有一部分为单向通行的道路,一部分 为双向通行的道路 ...

  5. 【BZOJ-1924】所驼门王的宝藏 Tarjan缩点(+拓扑排序) + 拓扑图DP

    1924: [Sdoi2010]所驼门王的宝藏 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 787  Solved: 318[Submit][Stat ...

  6. UVA 11324.The Largest Clique tarjan缩点+拓扑dp

    题目链接:https://vjudge.net/problem/UVA-11324 题意:求一个有向图中结点数最大的结点集,使得该结点集中任意两个结点u和v满足:要目u可以到达v,要么v可以到达u(相 ...

  7. Luogu3387 缩点 【tarjan】【DP】

    Luogu3387 缩点 题目背景 缩点+DP 题目描述 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点, ...

  8. 【模板】缩点(tarjan,DAG上DP)

    题目背景 缩点+DP 题目描述 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只 ...

  9. [ZJOI2007]最大半连通子图 (Tarjan缩点,拓扑排序,DP)

    题目链接 Solution 大概是个裸题. 可以考虑到,如果原图是一个有向无环图,那么其最大半联通子图就是最长的一条路. 于是直接 \(Tarjan\) 缩完点之后跑拓扑序 DP就好了. 同时由于是拓 ...

随机推荐

  1. 玩转VIM之将Vim全副武装

    玩转VIM之将Vim全副武装 懒癌末期的我貌似很久没有写博客了,已经欠了多少篇在计划中的博客我已然不好意思说了.好了,言归正传,在前三篇介绍了Vim作为代码编辑器之后可能会有人说,要学习那么多指令真的 ...

  2. Django admin源码剖析

    单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...

  3. 【题解搬运】PAT_A1016 Phone Bills

    从我原来的博客上搬运.原先blog作废. 题目 A long-distance telephone company charges its customers by the following rul ...

  4. cocos2d-x 粒子系统

    粒子系统是模拟自然界中的一些粒子的物理运动的效果,如烟雾,下雪,下雨,火,爆炸等. 粒子发射模式 粒子系统的发射模式的时候有两种方式:重力模式和半径模式. 粒子系统属性  属性名  行为  模式  d ...

  5. P5056 插头dp

    题面 Source: unordered_map: #include <iostream> #include <tr1/unordered_map> #include < ...

  6. java设计模式之装饰器模式以及在java中作用

    在JAVA I/O类库里有很多不同的功能组合情况,这些不同的功能组合都是使用装饰器模式实现的,下面以FilterInputStream为例介绍装饰器模式的使用  FilterInputStream和F ...

  7. js日期插件bootstrap-datetimepicker的使用

    js日期插件——bootstrap-datetimepicker的使用心得: 在大多说的web项目中,都有日期选择器的使用.如果自己写一个日期选择器的话,费时又费力,而且不一定能写出来_(:3 」∠) ...

  8. 最短路径——Dijkstra算法以及二叉堆优化(含证明)

    一般最短路径算法习惯性的分为两种:单源最短路径算法和全顶点之间最短路径.前者是计算出从一个点出发,到达所有其余可到达顶点的距离.后者是计算出图中所有点之间的路径距离. 单源最短路径 Dijkstra算 ...

  9. 在网站中配置MIME类型

    经常会遇到这样的情况,某种类型的文件不能够正常下载,*.7z,自定义的文件类型等,需要在配置文件里配置后才能正常下载. 打开Web.Config文件: <system.webServer> ...

  10. 3GPP规范命名规则解读

    http://blog.sina.com.cn/s/blog_6b10255301012co6.html 学习了解电信技术知识的一个很好的手段是阅读3GPP的规范.但是3GPP有大量的规范,我们可能经 ...