bzoj1040 内向树DP
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的更多相关文章
- bzoj1040 基环树森林dp
https://www.lydsy.com/JudgeOnline/problem.php?id=1040 Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社 ...
- 初涉基环外向树dp&&bzoj1040: [ZJOI2008]骑士
基环外向树dp竟然如此简单…… Description Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发 ...
- 【距离GDKOI:44天&GDOI:107天】【BZOJ1040】[ZJOI2008] 骑士 (环套树DP)
其实已经准备退役了,但GDOI之前还是会继续学下去的!!当成兴趣在学,已经对竞赛失去信心了的样子,我还是回去跪跪文化课吧QAQ 第一道环套树DP...其实思想挺简单的,就把环拆开,分类处理.若拆成开的 ...
- 【BZOJ1040】[ZJOI2008] 骑士(基环外向树DP)
点此看题面 大致题意: 给你一片基环外向树森林,如果选定了一个点,就不能选择与其相邻的节点.求选中点的最大权值和. 树形\(DP\) 此题应该是 树形\(DP\) 的一个升级版:基环外向树\(DP\) ...
- 【bzoj1040】[ZJOI2008]骑士 并查集+基环树dp
题目描述 Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火绵延五百里,在 ...
- BZOJ1040:骑士(基环树DP)
Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火绵延五百里,在和平环境中 ...
- 基环树DP
基环树DP Page1:问题 啥是基环树?就是在一棵树上增加一条边. Page2:基环树的几种情况 无向 有向:基环外向树,基环内向树. Page3:处理问题的基本方式 1.断环成树 2.分别处理树和 ...
- [BZOJ1791][IOI2008]Island岛屿(环套树DP)
同NOI2013快餐店(NOI出原题?),下面代码由于BZOJ栈空间过小会RE. 大致是对每个连通块找到环,在所有内向树做一遍DP,再在环上做两遍前缀和优化的DP. #include<cstdi ...
- 2018牛客网暑期ACM多校训练营(第二场):discount(基环树DP)
题意:有N个不同的商品,每个商品原价是Pi元,如果选择打折,可以减少Di元. 现在加一种规则,每个商品有一个友好商品Fai,如果i用原价买,则可以免费买Fai. 现在问买到所有物品的最小价格. 思路 ...
随机推荐
- ABP框架设置默认语言
在Global.asax文件中设置 private readonly IAbpWebLocalizationConfiguration _webLocalizationConfiguration; p ...
- 机器学习/逻辑回归(logistic regression)/--附python代码
个人分类: 机器学习 本文为吴恩达<机器学习>课程的读书笔记,并用python实现. 前一篇讲了线性回归,这一篇讲逻辑回归,有了上一篇的基础,这一篇的内容会显得比较简单. 逻辑回归(log ...
- 九度OJ--1165(C++)
#include <iostream>#include <string>#include <vector> using namespace std; int mai ...
- [leetcode-635-Design Log Storage System]
You are given several logs that each log contains a unique id and timestamp. Timestamp is a string t ...
- UVA 1085 House of Cards(对抗搜索)
Description Axel and Birgit like to play a card game in which they build a house of cards, gaining ...
- Linux SPI总线和设备驱动架构之四:SPI数据传输的队列化
我们知道,SPI数据传输可以有两种方式:同步方式和异步方式.所谓同步方式是指数据传输的发起者必须等待本次传输的结束,期间不能做其它事情,用代码来解释就是,调用传输的函数后,直到数据传输完成,函数才会返 ...
- [剑指Offer] 31.整数中1出现的次数
题目描述 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了. ...
- [剑指Offer] 15.反转链表
题目描述 输入一个链表,反转链表后,输出链表的所有元素. [思路1]三个指针在链表上同时滑动. /* struct ListNode { int val; struct ListNode *next; ...
- ai学习记录
界面:多个预编辑区:制作图形,使用的图形放到工作区内,不使用在预编区.没有Ctrl/Alt+delete的概念,没有前后景颜色.新建:分辨率:矢量软件和分辨率无关: 新建时候不要勾选对齐到像素网格 存 ...
- 处理大并发量订单处理的 KafKa部署总结
处理大并发量订单处理的 KafKa部署总结 今天要介绍的是消息中间件KafKa,应该说是一个很牛的中间件吧,背靠Apache 与很多有名的中间件搭配起来用效果更好哦 ,为什么不用RabbitMQ,因为 ...