BZOJ 1040 [ZJOI2008]骑士 (基环树+树形DP)
<题目链接>
题目大意:
Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英。他们劫富济贫,惩恶扬善,受到社会各界的赞扬。最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争。战火绵延五百里,在和平环境中安逸了数百年的Z国又怎能抵挡的住Y国的军队。于是人们把所有的希望都寄托在了骑士团的身上,就像期待有一个真龙天子的降生,带领正义打败邪恶。骑士团是肯定具有打败邪恶势力的能力的,但是骑士们互相之间往往有一些矛盾。每个骑士都有且仅有一个自己最厌恶的骑士(当然不是他自己),他是绝对不会与自己最厌恶的人一同出征的。战火绵延,人民生灵涂炭,组织起一个骑士军团加入战斗刻不容缓!国王交给了你一个艰巨的任务,从所有的骑士中选出一个骑士军团,使得军团内没有矛盾的两人(不存在一个骑士与他最痛恨的人一同被选入骑士军团的情况),并且,使得这支骑士军团最具有战斗力。为了描述战斗力,我们将骑士按照1至N编号,给每名骑士一个战斗力的估计,一个军团的战斗力为所有骑士的战斗力总和。
解题分析:
比较经典的基环树(环套树)。本题给出一个$n$条边$n$个点的有向图,我们可以发现,因为本题有向边表示这两个人至多只能出现其中一个,是用来表示一种关系的,所以在实际意义上,完全可以用无向边来代替。于是,本题就转化成了基环树森林,基环树的主要突破口就是要找出每个基环树的环(每个连通分量都是一颗基环树),然后将环中的一条边拆掉,使其变成一棵树,分别以拆掉的边的两个端点作为树的根,然后进行树形DP。本题就变成了对于树上有关系的两个点,只能选一个,使得最后的总价值最大,这就变成了一个比较经典的树形DP模型(比如上司的舞会)。
注意拆环的时候,强制一个点为根,并且不选,因为尽管我们拆除了那条边,但它还是正实存在的,所以只有不选的状态才能避免这两个点都被选中(防止违反题意)。
#include <bits/stdc++.h>
using namespace std; #define clr(a,b) memset(a,b,sizeof(a))
#define REP(i,s,t) for(int i=s;i<=t;i++)
const int N = 1e6+;
typedef long long ll;
struct Edge{ int to,nxt; }e[N<<];
int n,m,cnt,head[N];
int Ecut,rt,urt;
int w[N],vis[N];
ll dp[N][]; inline void init(){
cnt=;clr(head,-);clr(vis,);clr(dp,);
}
inline void add(int u,int v){ e[cnt]=(Edge){ v,head[u] };head[u]=cnt++; } void dfs(int u,int pre){
vis[u]=;
for(int i=head[u];~i;i=e[i].nxt){
int v=e[i].to;
if(v==pre)continue;
if(!vis[v])dfs(v,u);
else { //如果找到环了
rt=u,urt=v,Ecut=i; //记录下这个环的两个端点,并且记录这个拆除的边
}
}
}
void trdp(int u,int pre){
dp[u][]=w[u]; //表示选当前这个点的价值
dp[u][]=; //表示不选当前这个点的价值
for(int i=head[u];~i;i=e[i].nxt){
int v=e[i].to;
if(i==Ecut || i==(Ecut^) || v==pre)continue;
trdp(v,u);
dp[u][]+=dp[v][];
dp[u][]+=max(dp[v][],dp[v][]);
}
}
int main(){
while(~scanf("%d",&n)){
init();
REP(i,,n){
int now;scanf("%d%d",&w[i],&now);
add(i,now);add(now,i);
}
ll sum=;
REP(i,,n) if(!vis[i]) {
dfs(i,-); //基环树森林,每个连通分量中必有一个环
trdp(rt,-); //以拆分的两个点分别为根,进行树形DP
ll tmp = dp[rt][];
trdp(urt,-);
sum+=max(tmp,dp[urt][]);
}
printf("%lld\n",sum);
}
}
BZOJ 1040 [ZJOI2008]骑士 (基环树+树形DP)的更多相关文章
- BZOJ 1040: [ZJOI2008]骑士 基环加外向树
1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1190 Solved: 465[Submit][Status] ...
- bzoj 1040: [ZJOI2008]骑士 環套樹DP
1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1755 Solved: 690[Submit][Status] ...
- BZOJ 1040 骑士 基环树 树形DP
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1040 题目大意: Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫 ...
- day 2 下午 骑士 基环树+树形DP
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #inc ...
- 洛谷 P1453 城市环路 ( 基环树树形dp )
题目链接 题目背景 一座城市,往往会被人们划分为几个区域,例如住宅区.商业区.工业区等等.B市就被分为了以下的两个区域--城市中心和城市郊区.在着这两个区域的中间是一条围绕B市的环路,环路之内便是B市 ...
- bzoj 1040: [ZJOI2008]骑士 树形dp
题目链接 1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3054 Solved: 1162[Submit][S ...
- BZOJ 1040: [ZJOI2008]骑士 [DP 环套树]
传送门 题意:环套树的最大权独立集 一开始想处理出外向树树形$DP$然后找到环再做个环形$DP$ 然后看了看别人的题解其实只要断开环做两遍树形$DP$就行了...有道理! 注意不连通 然后洛谷时限再次 ...
- [BZOJ 1040][ZJOI2008]骑士
1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5403 Solved: 2060[Submit][Status ...
- Bzoj 1040 [ZJOI2008]骑士 题解
1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5368 Solved: 2044[Submit][Status ...
随机推荐
- FMC141-4路 250Msps/16bits ADC, FMC板卡
FMC141-4路 250Msps/16bits ADC, FMC板卡 一.产品概述: 本板卡基于 FMC 标准板卡,实现 4 路 16-bit/250Msps ADC 功能.遵循 VITA 57 标 ...
- 卷积神经网络 CNN 系列模型阐述
http://www.sohu.com/a/134347664_642762 Lenet,1986年 https://github.com/BVLC/caffe/blob/master/example ...
- 在Node.js环境下使用Express创建Web项目实例
序:如果你还不知道Node.js是什么,那么你可以先看看这篇:Node.js 究竟是什么?或者任何关于它的介绍. 一.安装Node.js 1.进入Node.js官网下载并安装 2.启动cmd输入命令查 ...
- 神仙dcx出的一道题
题目大意 \(\;\;\)在一个坐标系上, 以\((0, 0)\)为起点, 每走一步,可以从\((x,y)\)走到\((x+1,y),(x-1,y),(x,y+1),(x,y-1)\)中的一个点上, ...
- Python---基础---常用的内置模块
一. print(math.pow(4,3)) # 4的三次方 #幂运算 函数返回浮点型,幂运算返回整形 print(4**3) #fabs() 对一个数值获取他的绝对值 返回的也 ...
- vue中怎么使用vuex
做一个简单的vuex如何使用的介绍: 先安装: npm i vuex --save-dev 新建一个store文件夹, 在store文件夹中建一个index.js文件,在该文件中: i ...
- linux运维、架构之路-linux磁盘管理
一.企业中磁盘选购: 1.线上的业务,用SAS磁盘 2.线下的业务,用SATA磁盘,磁带库 3.线上高并发.小容量(多人浏览力图片)的业务,SSD磁盘 4.根据数据的访问热度,智能分析分层存储,SAT ...
- 大数据分析:hadoop工具
一.hadoop工具 Hadoop介绍: Hadoop是一个由Apache基金会所开发的分布式系统基础架构.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力进行高速运算和存储 ...
- Python_003(字符串的神操作)
一.编码问题 1.编码:计算机最早是ACSII码,美国人创造的,包含了英文字母(大写字母,小写字母)数字,标点等特殊符号; :共有7位0和1组成,表示128个ACSII码,但是计算机对7这个数字不敏感 ...
- 【HDOJ6699】Block Breaker(模拟)
题意:给定一个n*m的网格块,如果一个块水平或垂直方向没有相邻支撑就会掉下去 有q次询问,每次会掉下去一块,问连锁反应新掉下的块数 n,m<=2e3,q<=1e5 思路: #include ...