luogu2607/bzoj1040 [ZJOI2008]骑士 (基环树形dp)
N个点,每个点发出一条边,那么这个图的形状一定是一个基环树森林(如果有重边就会出现森林)
那我做f[0][x]和f[1][x]分别表示对于x子树,x这个点选还是不选所带来的最大价值
然后就变成了这好几个环上不能选相邻的点,最大的价值和
我们把这个环从N到1处断开,然后钦定一下1选还是不选,统计一下答案就可以了。
#include<bits/stdc++.h>
#define pa pair<int,int>
#define ll long long
using namespace std;
const int maxn=; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} int N;
int eg[maxn*][],egh[maxn],ect;
int dep[maxn],fa[maxn];
int root[maxn][],pct,rh[maxn],rct;
int stk[maxn],top[maxn];
ll f[][maxn];
bool flag[maxn],isroot[maxn],connected[maxn]; inline void adeg(int a,int b){
eg[++ect][]=b;eg[ect][]=egh[a];egh[a]=ect;
}
inline void adrot(int a,int b){
root[++rct][]=b;root[rct][]=rh[a];rh[a]=rct;
} void dfs1(int ii,int x){
flag[x]=;
//printf("%d %d %d\n",x,fa[x],dep[x]);
for(int i=egh[x];i!=-;i=eg[i][]){
int b=eg[i][];if(b==fa[x]) continue;
//printf("#%d %d %d %d %d\n",x,b,flag[b],i,eg[i][1]);
if(flag[b]){
if(connected[ii]) continue;
int u=x,v=b,lca,cnt=;
if(dep[u]<dep[v]) swap(u,v);
while(dep[u]!=dep[v]) adrot(ii,u),isroot[u]=,u=fa[u];
while(u!=v){
isroot[u]=isroot[v]=;
adrot(ii,u);
stk[++cnt]=v;
u=fa[u];v=fa[v];
}lca=u;isroot[lca]=;adrot(ii,lca);
for(int j=cnt;j;j--) adrot(ii,stk[j]);
connected[ii]=;
}else{
dep[b]=dep[x]+;fa[b]=x;
dfs1(ii,b);
}
}
} void dfs2(int x,int F){
for(int i=egh[x];i!=-;i=eg[i][]){
int b=eg[i][];if(b==F||isroot[b]) continue;
dfs2(b,x);
f[][x]+=max(f[][b],f[][b]);
f[][x]+=f[][b];
}
} inline ll solve(int p){
if(rh[p]==-) return max(f[][top[p]],f[][top[p]]);
ll re=;
ll g1=f[][root[rh[p]][]],g0=;
for(int i=root[rh[p]][];i!=-;i=root[i][]){
ll xx=max(g0,g1);
g1=g0+f[][root[i][]];
g0=xx+f[][root[i][]];
}re=max(re,g0); g1=,g0=f[][root[rh[p]][]];
for(int i=root[rh[p]][];i!=-;i=root[i][]){
ll xx=max(g0,g1);
g1=g0+f[][root[i][]];
g0=xx+f[][root[i][]];
}re=max(re,max(g0,g1));
return re;
} int main(){
int i,j,k;
//freopen("2607.in","r",stdin);
N=rd();memset(egh,-,sizeof(egh));
for(i=;i<=N;i++){
int a=rd(),b=rd();
f[][i]=a;
adeg(i,b);adeg(b,i);
}memset(rh,-,sizeof(rh));
for(i=;i<=N;i++){
if(!flag[i]) top[++pct]=i,dfs1(pct,i);
}
//for(i=1;i<=rct;i++) printf("!%d %d %d\n",i,root[i][0],root[i][1]);
for(i=;i<=rct;i++) dfs2(root[i][],);
ll ans=;
for(i=;i<=pct;i++){
ans+=solve(i);
}
printf("%lld\n",ans); return ;
}
luogu2607/bzoj1040 [ZJOI2008]骑士 (基环树形dp)的更多相关文章
- [BZOJ1040][ZJOI2008]骑士 基环树DP
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1040 题目给出了$n$个点和$n$条无向边,即一棵基环树或者基环树森林. 如果题目给的关系 ...
- 2018.11.06 bzoj1040: [ZJOI2008]骑士(树形dp)
传送门 由题可知给出的是基环森林. 因此对于每个基环森林找到环断开dpdpdp两次就行了. 代码: #include<bits/stdc++.h> using namespace std; ...
- BZOJ_1040_[ZJOI2008]骑士_树形DP
BZOJ_1040_[ZJOI2008]骑士_树形DP 题意: Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各 界的赞扬.最近发生了一件可怕的事情,邪 ...
- [bzoj1040][ZJOI2008]骑士_树形dp_基环树_并查集
骑士 bzoj-1040 ZJOI-2008 题目大意:n个骑士,每个骑士有权值val和一个讨厌的骑士.如果一个骑士讨厌另一个骑士那么他们将不会一起出战.问出战的骑士最大atk是多少. 注释:$1\l ...
- 【洛谷】2607: [ZJOI2008]骑士【树形DP】【基环树】
P2607 [ZJOI2008]骑士 题目描述 Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的Y国发动了一 ...
- BZOJ1040 [ZJOI2008]骑士 基环树林(环套树) 树形动态规划
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题意概括 有n个人,每一个人有一个最恨的人. 并且,每一个人有一个权值. 一个人不可以和他最恨的人同时被选中. 现在请你求出在 ...
- [ZJOI2008] 骑士 - 基环树dp
一类基环树dp都是这个套路吧 随便拆掉环上的一条边 然后跑树形dp,设\(f[i][0/1]\)表示以第\(i\)个人为根的子树,第\(i\)个人选或不选,能收获的最大值 以断点\(u,v\)为根分别 ...
- [BZOJ1040][ZJOI2008]骑士(环套树dp)
1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5816 Solved: 2263[Submit][Status ...
- BZOJ1040: [ZJOI2008]骑士 树套环DP
题意:一个图n个点n条边保证点能互相到达,ab有边意味着ab互相厌恶,求一个集合,使得集合里元素最多而且没有人互相厌恶 删去环上一条边树形dp,比如删掉的边连着a,b,那么先dp出不选a的最大值,再d ...
随机推荐
- Libgdx学习记录28——创建Desktop程序
1.新建Java Project. 2.添加libs,添加相关的jar文件. 3. 在Project Build Path中,添加Reference. 4. 添加文件夹assets,并右键Build ...
- item 3: 理解decltype
本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 decltype是一个奇怪的东西.给出一个名字或者一个表达式,de ...
- inode 软/硬链接
一.inode是什么? 理解inode,要从文件储存说起. 文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector).每个扇区储存512字节(相当于0.5KB). 操作系统 ...
- Jenkins日常运维笔记-重启数据覆盖问题、迁移、基于java代码发版(maven构建)
之前在公司机房部署了一套jenkins环境,现需要迁移至IDC机房服务器上,迁移过程中记录了一些细节:1)jenkins默认的主目录放在当前用户家目录路径下的.jenkins目录中.如jenkins使 ...
- 矩形A + B HDU2524
题意 给你n*m的棋盘问有多少个矩形 分析 先看只有一行或一列的情况有1+2+....+n个,因为矩形的类型有1个最小单位格子n个,2个最小单位格子n-1个,n个最小单位格子有一个 code #inc ...
- 不重叠的线段 51nod
链接 [http://www.51nod.com/onlineJudge/questionCode.html#problemId=1133¬iceId=468024] 题意 X轴上有N条 ...
- beta阶段性能指标测试
性能指标概况 安装耗时 启动耗时 CPU占用 内存占用 电池温度 网络流量 平均值 5.48s 1.04s 1.61% 18.68MB 32.44℃ 93.78B 峰值 131.74s 5.13s 5 ...
- 个人阅读作业 --软件工程M1/M2总结
软件工程M1/M2总结 写在前面的话: 这学期的软件工程伴着考期的展开逐渐落下帷幕,回顾这学期的软件工程,我感觉我的热情在一次又一次的失落中逐步消耗殆尽,每个人对于这门课的体验都会有所不同吧,可以确定 ...
- Junit4测试用例
一.题目简介 测试一元一次方程的求解 二.源码的github链接 https://github.com/liujing1994/test1 三.所设计的模块测试用例.测试结果截图 一元一次方程测试 ...
- JavaScript中的cookie
cookie本身没什么可介绍的,但是cookie在JavaScript中,有很多需要注意的 首先,cookie在JavaScript中,是window.document对象的一个属性,所以访问cook ...