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 ...
随机推荐
- java缓存技术的介绍
一.什么是缓存1.Cache是高速缓冲存储器 一种特殊的存储器子系统,其中复制了频繁使用的数据以利于快速访问2.凡是位于速度相差较大的两种硬件/软件之间的,用于协调两者数据传输速度差异的结构,均可称之 ...
- Hybrid小程序混合开发之路 - 数据交互
HTML+CSS是历史悠久.超高自由度.控制精准.表现能力极强.编码简单.学习门槛超低.真跨平台的一种UI界面开发方式. 本文介绍的是微信小程序和H5混合开发的一种数据交互方式. 很多应用在原生界面中 ...
- 案例学Python--案例四:Django实现一个网站的雏形(2)
续上篇,用Django创建了一个Web,我们肯定想展示自己的页面,简单点,我们想看到自己的HelloWorld.此处要从项目的配置说起,方法和路径配对了,展现页面分分钟的事情. 先上效果图吧: ...
- item 4: 知道怎么去看推导的类型
本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 对于推导类型结果的查看,根据不同的软件开发阶段,你想知道的信息的不 ...
- 【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--请求处理结果适配篇(7/8)
文章目录 前情概要 前面一大坨一大坨的代码把route.controller.action.attribute都搞完事儿了,最后剩下一部分功能就是串起来的调用. 那接下就说个说第二个中间件,也是最后一 ...
- 记一次艰难的jquery easy-ui ajax post 体验
分享的经验和教训是: 1.jquery easy-ui ajax post 复杂的Json给后端解析,后端如果接收和解析 2.asp.net webform jquery easy-ui datagr ...
- SKINNY加密算法详解(无代码,仅加密)
原作者论文请参考<The SKINNY Family of Block Ciphers and Its Low-Latency Variant MANTIS> 地址为:https://li ...
- Oracle数据库设置为归档模式的操作方法
Oracle归档模式非常非常重要!对于有些数据库刚装好后可能是非归档模式,这是很危险的!为了安全起见,一定要谨记:对于Oracle数据库,一定要设置为归档模式,尤其是生产库,只有这样才能实现数据库的有 ...
- SpringCloud设定Feign底层实现
1. 概述 版本: spring-boot: 1.5.9.RELEASE spring-cloud: Dalston.SR5 在默认情况下 spring cloud feign在进行各个子服务之间的 ...
- Coolest Ski Route-不定起点和终点----在有向变的情况下---求最长路
这题最开始给你了N个点,M条边,边是单向边,问不指定起点和终点,最长路是什么??? 脑补一下,不定起点和终点的最短路,用弗洛伊德算法搞一搞,但是...那个垃圾算法的复杂度是N^3的,但是这个算法的M高 ...