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. Android各版本代号、版本号、API/NDK级别、发布时间

    代号 版本号 API/NDK级别 发布时间 牛轧糖 Nougat 7.1.2 API level 25 2017-2 7.1.1 2016-10 7.0 API level 24 2016-05 棉花 ...

  2. MD5、SHA校验命令

    linux系统的软件很多时候都以境像的方式提供下载,但我们如何确实下载的文件是没有被篡改过的呢?Linux中一般用对下载的文件进行MD5和SHA校验来确认. MD5 我们拿iptraf软件来试验: 我 ...

  3. Sqlite Datetime类型详解

    日期和时间函数 date(timestring, modifier, modifier, ...) time(timestring, modifier, modifier, ...) datetime ...

  4. 第三十四篇 Python面向对象之 反射(自省)

    什么是反射? 反射的概念是由Smith在1982年提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序语 ...

  5. CSS3 : transform 与 transform-origin 属性可以使元素样式发生转变

    CSS3 : transform 用于元素样式的转变,比如使元素发生位移.角度变化.拉伸缩小.按指定角度歪斜 transform结合transition可实现各类动画效果 transform : tr ...

  6. QR码与DM码的区别

    DM无法表现汉字等其他形式,而QR码能用数据压缩方式来表示汉字,仅用13bit即可表示一个汉字,比其他二维条码表示汉字的效率提高了20%.相较而言,DM码信息容量小,应用简单.而QR在汉字处理上更有优 ...

  7. 链上链下交互 以太坊Dapp接口开发

    主要是指的是用NodeJs调用 提供接口供前端使用 用户查询和转账 以太坊Dapp项目 众筹项目 功能需求 路人 查看所有众筹项目, 2 @ OK 根据众筹项目的address获取该众筹的详情 (参与 ...

  8. lintcode-76-最长上升子序列

    76-最长上升子序列 给定一个整数序列,找到最长上升子序列(LIS),返回LIS的长度. 说明 最长上升子序列的定义: 最长上升子序列问题是在一个无序的给定序列中找到一个尽可能长的由低到高排列的子序列 ...

  9. 正则awk和查看文件行数

    [root@WebServer aa]# cat oldboy.txt I am oldboy myqq is 49000448[root@WebServer aa]# cat oldboy.txt ...

  10. ScrollBarsEnabled的使用

    在WinForm中通过WebBrowser获取网页,我想把WebBrowser的ScollBar去掉,我的网页不需要滚动条. 设置方法如下:单击WebBrowser设计页面,在属性页面有一个Scrol ...