【树形dp】Bzoj 1040骑士
Description
Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英。他们劫富济贫,惩恶扬善,受到社会各界的赞扬。最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争。战火绵延五百里,在和平环境中安逸了数百年的Z国又怎能抵挡的住Y国的军队。于是人们把所有的希望都寄托在了骑士团的身上,就像期待有一个真龙天子的降生,带领正义打败邪恶。骑士团是肯定具有打败邪恶势力的能力的,但是骑士们互相之间往往有一些矛盾。每个骑士都有且仅有一个自己最厌恶的骑士(当然不是他自己),他是绝对不会与自己最厌恶的人一同出征的。战火绵延,人民生灵涂炭,组织起一个骑士军团加入战斗刻不容缓!国王交给了你一个艰巨的任务,从所有的骑士中选出一个骑士军团,使得军团内没有矛盾的两人(不存在一个骑士与他最痛恨的人一同被选入骑士军团的情况),并且,使得这支骑士军团最具有战斗力。为了描述战斗力,我们将骑士按照1至N编号,给每名骑士一个战斗力的估计,一个军团的战斗力为所有骑士的战斗力总和。
Input
第一行包含一个正整数N,描述骑士团的人数。接下来N行,每行两个正整数,按顺序描述每一名骑士的战斗力和他最痛恨的骑士。
Output
应包含一行,包含一个整数,表示你所选出的骑士军团的战斗力。
Sample Input
10 2
20 3
30 1
Sample Output
「数据规模」
对于30%的测试数据,满足N ≤ 10;
对于60%的测试数据,满足N ≤ 100;
对于80%的测试数据,满足N ≤ 10 000。
对于100%的测试数据,满足N ≤ 1 000 000,每名骑士的战斗力都是不大于 1 000 000的正整数。
分析
这道题应该是一个无向的边。
因为一个骑士觉得另一个骑士丑他们俩就走不到一起。所以整个图实际上是一个无向环森林。
对于每一棵环套树,先dfs找环,找到环以后断环为链并将断开的两个点强制其中一个点为根且不选做一次树形DP,对另一个点做同样操作。
取两次结果最大值加入ans
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
const int N = 1e6+;
#define ll long long
using namespace std;
int n,cnt;ll ans,answer;
int v[N],d[N],head[N],to[N],next[N],ez[N],b[N];
ll dp[N][],f[N][];
bool vis[N];
void Ins(int a,int b){
cnt++;
to[cnt]=b;
next[cnt]=head[a];
head[a]=cnt;
}
void init(){
int i,k;
scanf("%d",&n);
for(i=;i<=n;i++){
scanf("%d%d",&v[i],&k);
Ins(k,i);
d[i]=k;
}
}
void dp1(int x){
dp[x][]=v[x];dp[x][]=;
vis[x]=;
int i=head[x];
while(i>){
dp1(to[i]);
dp[x][]+=max(dp[to[i]][],dp[to[i]][]);
dp[x][]+=dp[to[i]][];
i=next[i];
}
}
void Find(){
int k;
ans=;
f[][]=;f[][]=;
f[][]=dp[b[]][];
f[][]=dp[b[]][];
for(int i=;i<=b[];i++){
k=b[i];
f[i][]=f[i-][]+dp[k][];
f[i][]=max(f[i-][],f[i-][])+dp[k][];
f[i][]=f[i-][]+dp[k][];
f[i][]=max(f[i-][],f[i-][])+dp[k][];
}
ans=max(f[b[]][],max(f[b[]][],f[b[]][]));
}
void solve(){
int i,k,j,now;
for(i=;i<=n;i++){
if(vis[i])continue;
b[]=;
k=i;
while(!vis[k]){
vis[k]=;
k=d[k];
ez[d[k]]=k;
}
now=k;
while(){
i=head[k];
dp[k][]=v[k];
while(i>){
if(to[i]!=ez[k])
{dp1(to[i]);
dp[k][]+=max(dp[to[i]][],dp[to[i]][]);
dp[k][]+=dp[to[i]][];}
i=next[i];
}
b[]++;b[b[]]=k;
k=d[k];
if(k==now)
break;
}
Find();
answer+=ans;
}
printf("%lld",answer);
}
int main(){
init();
solve();
return ;
}
【树形dp】Bzoj 1040骑士的更多相关文章
- BZOJ 1040 骑士(环套树DP)
如果m=n-1,显然这就是一个经典的树形dp. 现在是m=n,这是一个环套树森林,破掉这个环后,就成了一个树,那么这条破开的边连接的两个顶点不能同时选择.我们可以对这两个点进行两次树形DP根不选的情况 ...
- 【树形DP】BZOJ1040-[ZJOI2008]骑士
[题目大意] 有n个骑士,给出他们的能力值和最痛恨的一位骑士.选出一个骑士军团,使得军团内没有矛盾的两人(不存在一个骑士与他最痛恨的人一同被选入骑士军团的情况),并且,使得这支骑士军团最具有战斗力,求 ...
- BZOJ 1040 骑士 基环树 树形DP
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1040 题目大意: Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫 ...
- [bzoj] 1040 骑士 || 基环外向树dp
原题 给出n个点n条边和每个点的点权,一条边的两个断点不能同时选择,问最大可以选多少. //图是一张基环外向树森林 是不是很像舞会啊- 就是多了一条边. 所以我们考虑一下对于一棵基环外向树,拆掉一条在 ...
- 【树形DP】ZJOI2008 骑士
题目内容 洛谷链接 有\(n\)位骑士,每个人的战力可能不同,并且每一个人都有且仅有一个憎恨的人,互相憎恨的人不能在同一队中. 求组合为一个骑士队的最大战斗力. PS:可以去看看题目背景学学历史(雾) ...
- bzoj 1040 骑士
这题真不爽,各种WA,写个题解浏览器还挂了,真不爽. 所以不多说了,就说关于判断是否是父节点的问题,不能直接判,会有重边,这种情况只能用编号判,传进去入边的编号,(k^1) != fa,这样就可以了. ...
- bzoj 1040 [ZJOI2008]骑士(基环外向树,树形DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1040 [题意] 给一个基环森林,每个点有一个权值,求一个点集使得点集中的点无边相连且权 ...
- BZOJ 1040 ZJOI 2008 骑士 基环树林+树形DP
题目大意:有一些骑士.他们每个人都有一个权值.可是因为一些问题,每个骑士都特别讨厌还有一个骑士.所以不能把他们安排在一起.求这些骑士所组成的编队的最大权值和是多少. 思路:首先貌似是有向图的样子,可是 ...
- BZOJ 1040:[ZJOI2008]骑士(环套外向树+树形DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1040 [题目大意] 给出环套外向树森林,求最大权独立集. [题解] 我们对于每个连通块 ...
随机推荐
- Spring Boot笔记(五) SpringBoot 集成Lombok 插件
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 为了减少代码量,为当前项目添加 lombok 来优雅编码 Lombok 插件安装: a . 添加依赖: ...
- Java实现 蓝桥杯 算法训练 猴子吃包子(暴力)
试题 算法训练 猴子吃包子 问题描述 从前,有一只吃包子很厉害的猴子,它可以吃无数个包子,但是,它吃不同的包子速度也不同:肉包每秒钟吃x个:韭菜包每秒钟吃y个:没有馅的包子每秒钟吃z个:现在有x1个肉 ...
- Java实现十六进制转十进制
基础练习 十六进制转十进制 时间限制:1.0s 内存限制:512.0MB 提交此题 锦囊1 锦囊2 问题描述 从键盘输入一个不超过8位的正的十六进制数字符串,将它转换为正的十进制数后输出. 注:十六进 ...
- Java实现 蓝桥杯 历届试题 小数第n位
历届试题 小数第n位 时间限制:1.0s 内存限制:256.0MB 问题描述 我们知道,整数做除法时,有时得到有限小数,有时得到无限循环小数. 如果我们把有限小数的末尾加上无限多个0,它们就有了统一的 ...
- Java实现 蓝桥杯VIP 算法提高 质因数2
算法提高 质因数2 时间限制:1.0s 内存限制:256.0MB 将一个正整数N(1<N<32768)分解质因数,把质因数按从小到大的顺序输出.最后输出质因数的个数. 输入格式 一行,一个 ...
- PAT 科学计数法
科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [+-][1-9].[0-9]+E[+-][0-9]+,即数字的整数部分只有 1 位,小数部分至少有 1 位,该数字及其指 ...
- 判断IP是否是IPV4
bool isVaildIp(const char *ip) { int dots = 0; /*字符.的个数*/ int setions = 0; /*ip每一部分总和(0-255)*/ if (N ...
- OC语言
// // main.m // 测试题05 // // Created by yang sanchao on 9/12/15. // Copyright (c) 2015 yang sanchao. ...
- [noi.ac省选模拟赛]第12场题解集合
题目 比赛界面. T1 数据范围明示直接\(O(n^2)\)计算,问题就在如何快速计算. 树上路径统计通常会用到差分方法.这里有两棵树,因此我们可以做"差分套差分",在 A 树上对 ...
- conda 切换为国内源
添加清华源 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda con ...