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)的更多相关文章

  1. [BZOJ1040][ZJOI2008]骑士 基环树DP

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1040 题目给出了$n$个点和$n$条无向边,即一棵基环树或者基环树森林. 如果题目给的关系 ...

  2. 2018.11.06 bzoj1040: [ZJOI2008]骑士(树形dp)

    传送门 由题可知给出的是基环森林. 因此对于每个基环森林找到环断开dpdpdp两次就行了. 代码: #include<bits/stdc++.h> using namespace std; ...

  3. BZOJ_1040_[ZJOI2008]骑士_树形DP

    BZOJ_1040_[ZJOI2008]骑士_树形DP 题意: Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各 界的赞扬.最近发生了一件可怕的事情,邪 ...

  4. [bzoj1040][ZJOI2008]骑士_树形dp_基环树_并查集

    骑士 bzoj-1040 ZJOI-2008 题目大意:n个骑士,每个骑士有权值val和一个讨厌的骑士.如果一个骑士讨厌另一个骑士那么他们将不会一起出战.问出战的骑士最大atk是多少. 注释:$1\l ...

  5. 【洛谷】2607: [ZJOI2008]骑士【树形DP】【基环树】

    P2607 [ZJOI2008]骑士 题目描述 Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的Y国发动了一 ...

  6. BZOJ1040 [ZJOI2008]骑士 基环树林(环套树) 树形动态规划

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题意概括 有n个人,每一个人有一个最恨的人. 并且,每一个人有一个权值. 一个人不可以和他最恨的人同时被选中. 现在请你求出在 ...

  7. [ZJOI2008] 骑士 - 基环树dp

    一类基环树dp都是这个套路吧 随便拆掉环上的一条边 然后跑树形dp,设\(f[i][0/1]\)表示以第\(i\)个人为根的子树,第\(i\)个人选或不选,能收获的最大值 以断点\(u,v\)为根分别 ...

  8. [BZOJ1040][ZJOI2008]骑士(环套树dp)

    1040: [ZJOI2008]骑士 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5816  Solved: 2263[Submit][Status ...

  9. BZOJ1040: [ZJOI2008]骑士 树套环DP

    题意:一个图n个点n条边保证点能互相到达,ab有边意味着ab互相厌恶,求一个集合,使得集合里元素最多而且没有人互相厌恶 删去环上一条边树形dp,比如删掉的边连着a,b,那么先dp出不选a的最大值,再d ...

随机推荐

  1. 苹果企业账号打包发布App的详细流程

    原文链接:http://www.cnblogs.com/mddblog/p/4718228.html 一.通过企业账号申请证书 1 Certificate Signing Request (CSR)文 ...

  2. 调用不同目录类的protected构造器

    一.问题 二.分析 调用不同目录类的protected构造器,IDE报错. 二.解决办法: 后面添加一个{}就可以了

  3. html5录音支持pc和Android、ios部分浏览器,微信也是支持的,JavaScript getUserMedia

    以前在前人基础上重复造了一个网页录音的轮子,顺带把github仓库使用研究了一下,扔到了github上. 优势在于结构简单,可插拔式的录音格式支持,几乎可以支持任意格式(前提有相应的编码器):默认提供 ...

  4. Linux 小记 — Ubuntu 自动化配置

    前言 工欲善其事,必先利其器.经过多次的重复配置 ubuntu 开发坏境,我终于决定花点时间总结一下,并将其写成一个自动化配置脚本.服务器实例:ubuntu 16.04,技术栈:shell,pytho ...

  5. Mysql8.0的登录大坑……(忘记登录密码也可以这么搞)

    关于安装和使用就不说了,属于基本操作了: 我来重点记录一下关于使用前,使用navicat登录的时候报错,1130和2059 查看安装后随机生成的密码: grep 'temporary password ...

  6. LVM : 快照

    LVM 机制还提供了对 LV 做快照的功能,也就是说可以给文件系统做一个备份,这也是设计 LVM 快照的主要目的.LVM 的快照功能采用写时复制技术(Copy-On-Write,COW),这比传统的备 ...

  7. Linux ip forward

    Linux 默认带有 ip forward 功能,只不过因为各种原因,默认的配置把该功能关闭了.本文通过 demo 来演示 Linux 的 ip forward 功能,具体场景为:开启 Linux 的 ...

  8. Ionic2 下处理 Android 设备下返回按钮的事件

    原文发表于我的技术博客 本文分享了 Ionic2 下处理 Android 设备下返回按钮的事件,供参考. 原文发表于我的技术博客 代码中我分享了如何捕捉 Ionic2 项目在 Android 设备下返 ...

  9. SpringBoot笔记

    官网: http://springboot.fun/ 收集到一个比较全的: https://blog.csdn.net/xiaoyu411502/article/details/52474037 Id ...

  10. 磁盘挂载问题:Fdisk最大只能创建2T分区的盘,超过2T使用parted

    需求说明:云服务器上买了一块8T的磁盘,准备挂载到服务器上的/data目录下. ===================================parted命令说明=============== ...