2013-11-17 08:52

原题传送门http://www.lydsy.com/JudgeOnline/problem.php?id=1040

N个骑士,每个人有一个仇人,那么,每个骑士只有一个后继,将他和他憎恨的人连边,就组成了

一颗内向树,内向树可以看成环儿上挂一堆树,那么我们对于每个环儿上的点,求出以该点为根节点

的子树,取不取该根节点的价值(树P就好了,类似于没有上司的舞会),然后我们得到了一个环儿

知道每个点取不取的价值,求最大价值,那么我们可以破环为链,固定第一个取不取,然后DP,如果

第一个取,那么答案就是c[tot,0],不取的话答案就是max(c[tot,1],c[tot,0]),tot为环最后一个节点

然后取两个的最大值就好了,因为可能图有多个块,所以累加每个块的最大值就是ans。

Ps:我知道我的代码写的长。。。。风格。。。

//By BLADEVIL
var
n :int64;
pre, last, other :array[..] of int64;
l :int64;
low, dfn, stack, key :array[..] of int64;
flag :array[..] of boolean;
time :int64;
que :array[..] of int64;
fuck :int64;
tot :int64;
v :array[..] of int64;
w, c :array[..,..] of int64;
finish :array[..] of boolean;
ans :int64; function min(a,b:int64):int64;
begin
if a>b then min:=b else min:=a;
end; function max(a,b:int64):int64;
begin
if a>b then max:=a else max:=b;
end; procedure connect(x,y:int64);
begin
inc(l);
pre[l]:=last[x];
last[x]:=l;
other[l]:=y;
end; procedure init;
var
i :longint;
y :int64;
begin
read(n);
for i:= to n do
begin
read(v[i],y);
connect(y,i);
end;
end; procedure dfs(x:int64);
var
p, q :int64;
cur :int64;
begin
inc(time);
dfn[x]:=time;
low[x]:=time;
inc(tot);
stack[tot]:=x;
flag[x]:=true; q:=last[x];
while q<> do
begin
p:=other[q];
if dfn[p]= then
begin
dfs(p);
low[x]:=min(low[x],low[p]);
end else
if flag[p] then low[x]:=min(low[x],dfn[p]);
q:=pre[q];
end; cur:=-;
if dfn[x]=low[x] then
begin
while cur<>x do
begin
cur:=stack[tot];
dec(tot);
flag[cur]:=false;
key[cur]:=x;
end;
end;
end; procedure doit(x:int64);
var
q, p :int64;
h, t :int64;
cur :int64;
i :longint;
now :int64; begin
t:=; h:=;
que[]:=x; q:=last[x];
while t<>h do
begin
inc(h);
cur:=que[h];
q:=last[cur];
while q<> do
begin
p:=other[q];
if key[p]=fuck then
begin
q:=pre[q];
continue;
end;
inc(t);
que[t]:=p;
q:=pre[q];
end;
end;
for i:=t downto do
begin
now:=que[i];
q:=last[now];
w[now,]:=v[now];
if q= then w[now,]:=v[now];
while q<> do
begin
p:=other[q];
if key[p]<>fuck then
begin
w[now,]:=w[now,]+max(w[p,],w[p,]);
w[now,]:=w[now,]+w[p,];
end;
q:=pre[q];
end;
end;
end; procedure main;
var
i, j :longint;
q, p :int64;
f :boolean;
now :int64; begin
for i:= to n do if dfn[i]= then dfs(i);
for i:= to n do if (low[i]<>dfn[i]) and (not finish[key[i]]) then
begin
fuck:=key[i]; finish[fuck]:=true;
for j:= to n do if key[j]=fuck then doit(j);
fillchar(flag,sizeof(flag),false);
for j:= to n do if key[j]=fuck then break;
fillchar(que,sizeof(que),);
que[]:=j; tot:=;
f:=false;
while true do
begin
q:=last[que[tot]];
while q<> do
begin
p:=other[q];
if flag[p] then
begin
f:=true;
break;
end;
if key[p]=fuck then
begin
inc(tot);
que[tot]:=p;
flag[p]:=true;
end;
q:=pre[q];
end;
if f then break;
end;
fillchar(c,sizeof(c),);
c[que[],]:=-maxlongint; c[que[],]:=w[que[],];
for j:= to tot- do
begin
c[que[j],]:=max(c[que[j-],],c[que[j-],])+w[que[j],];
c[que[j],]:=c[que[j-],]+w[que[j],];
end;
now:=-maxlongint;
for j:= to tot- do now:=max(now,max(c[que[j],],c[que[j],]));
fillchar(c,sizeof(c),);
c[que[],]:=w[que[],]; c[que[],]:=-maxlongint;
for j:= to tot- do
begin
c[que[j],]:=max(c[que[j-],],c[que[j-],])+w[que[j],];
c[que[j],]:=c[que[j-],]+w[que[j],];
end;
for j:= to tot- do now:=max(now,max(c[que[j],],c[que[j],]));
now:=max(now,c[que[tot-],]);
inc(ans,now);
end;
writeln(ans);
end; begin
init;
main;
end.

bzoj1040 内向树DP的更多相关文章

  1. bzoj1040 基环树森林dp

    https://www.lydsy.com/JudgeOnline/problem.php?id=1040 Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社 ...

  2. 初涉基环外向树dp&&bzoj1040: [ZJOI2008]骑士

    基环外向树dp竟然如此简单…… Description Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发 ...

  3. 【距离GDKOI:44天&GDOI:107天】【BZOJ1040】[ZJOI2008] 骑士 (环套树DP)

    其实已经准备退役了,但GDOI之前还是会继续学下去的!!当成兴趣在学,已经对竞赛失去信心了的样子,我还是回去跪跪文化课吧QAQ 第一道环套树DP...其实思想挺简单的,就把环拆开,分类处理.若拆成开的 ...

  4. 【BZOJ1040】[ZJOI2008] 骑士(基环外向树DP)

    点此看题面 大致题意: 给你一片基环外向树森林,如果选定了一个点,就不能选择与其相邻的节点.求选中点的最大权值和. 树形\(DP\) 此题应该是 树形\(DP\) 的一个升级版:基环外向树\(DP\) ...

  5. 【bzoj1040】[ZJOI2008]骑士 并查集+基环树dp

    题目描述 Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火绵延五百里,在 ...

  6. BZOJ1040:骑士(基环树DP)

    Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火绵延五百里,在和平环境中 ...

  7. 基环树DP

    基环树DP Page1:问题 啥是基环树?就是在一棵树上增加一条边. Page2:基环树的几种情况 无向 有向:基环外向树,基环内向树. Page3:处理问题的基本方式 1.断环成树 2.分别处理树和 ...

  8. [BZOJ1791][IOI2008]Island岛屿(环套树DP)

    同NOI2013快餐店(NOI出原题?),下面代码由于BZOJ栈空间过小会RE. 大致是对每个连通块找到环,在所有内向树做一遍DP,再在环上做两遍前缀和优化的DP. #include<cstdi ...

  9. 2018牛客网暑期ACM多校训练营(第二场):discount(基环树DP)

    题意:有N个不同的商品,每个商品原价是Pi元,如果选择打折,可以减少Di元.  现在加一种规则,每个商品有一个友好商品Fai,如果i用原价买,则可以免费买Fai. 现在问买到所有物品的最小价格. 思路 ...

随机推荐

  1. BI领军者之一Tableau试用浅谈

    下图是最新的Gartner BI Magic Quadrant,其中领军者之一的Tableau表现的异常突出,执行力象限上直接甩开其它产品一条街,前瞻性象限上略微超越了MSBI,怀着无比的好奇心,特意 ...

  2. 「题目代码」P1029~P1033(Java)

    1029 C基础-求解方程 import java.util.*; import java.io.*; import java.math.BigInteger; public class Main { ...

  3. 调度器&负载均衡调度算法整理

    一.Linux 调度器   Linux中进程调度器已经经过很多次改进了,目前核心调度器是在CFS(Completely Fair Scheduler),从2.6.23开始被作为默认调度器.用作者Ing ...

  4. LeetCode 24——两两交换链表中的节点

    1. 题目 2. 解答 新建一个哨兵结点作为头结点,然后每次交换相邻两个结点.并依次将它们连接到新链表中去,再将原链表中后面的结点也串到新链表后面.直至到达链尾或者剩余一个节点,则此时返回新链表的头结 ...

  5. lintcode-91-最小调整代价

    91-最小调整代价 给一个整数数组,调整每个数的大小,使得相邻的两个数的差不大于一个给定的整数target,调整每个数的代价为调整前后的差的绝对值,求调整代价之和最小是多少. 注意事项 你可以假设数组 ...

  6. 《学习OpenCV》课后习题解答9

    题目:(P126) 创建一个程序,使其读入并显示一幅图像.当用户鼠标点击图像时,获取图像对应像素的颜色值(BGR),并在图像上点击鼠标处用文本将颜色值显示出来. 解答: 本题关键是会用cvGet2D获 ...

  7. CSS position属性---absolute与relative

    详情请点击此链接 http://www.cnblogs.com/polk6/archive/2013/07/26/3214847.html

  8. NAPT 分为锥型(Cone)和 对称型(Symmetric)

    NAPT 分为锥型(Cone)和 对称型(Symmetric) 链接:https://www.zhihu.com/question/38729355/answer/86531260 实际上大部运营商提 ...

  9. oracle 导入导出语句

    imp USERID/PSD@SID file='D:\1.dmp' full=y statistics=none exp USERID/PSD@SID file='D:\1.dmp' tables= ...

  10. ZOJ 3496 Assignment | 二分+有上下界网络流

    题目: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3496 大概意思:给你一个网络,有源汇,在保证最大流的情况下求下面两 ...