【树形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 [题目大意] 给出环套外向树森林,求最大权独立集. [题解] 我们对于每个连通块 ...
随机推荐
- Java实现 LeetCode 593 有效的正方形(判断正方形)
593. 有效的正方形 给定二维空间中四点的坐标,返回四点是否可以构造一个正方形. 一个点的坐标(x,y)由一个有两个整数的整数数组表示. 示例: 输入: p1 = [0,0], p2 = [1,1] ...
- Java实现 LeetCode 102 二叉树的层次遍历
102. 二叉树的层次遍历 给定一个二叉树,返回其按层次遍历的节点值. (即逐层地,从左到右访问所有节点). 例如: 给定二叉树: [3,9,20,null,null,15,7], 3 / \ 9 2 ...
- Java实现 蓝桥杯VIP 算法提高 企业奖金发放
算法提高 企业奖金发放 时间限制:1.0s 内存限制:512.0MB 企业发放的奖金根据利润提成.利润低于或等于10万元时,奖金可提10%:利润高于10万元,低于20万元时,低于10万元的部分按10% ...
- Java实现字符串编辑距离
1 问题描述 给定一个源串和目标串,能够进行如下操作: 在任意位置上插入一个字符: 替换掉任意字符: 删除任意字符. 写一个程序,实现返回最小操作次数,使得对源串进行上述这些操作后等于目标串. 2 解 ...
- java实现 猜数字游戏
猜数字游戏 猜数字 很多人都玩过这个游戏:甲在心中想好一个数字,乙来猜.每猜一个数字,甲必须告诉他是猜大了,猜小了,还是刚好猜中了.下列的代码模拟了这个过程.其中用户充当甲的角色,计算机充当乙的角色. ...
- java实现第六届蓝桥杯格子中输出
格子中输出 格子中输出 stringInGrid方法会在一个指定大小的格子中打印指定的字符串. 要求字符串在水平.垂直两个方向上都居中. 如果字符串太长,就截断. 如果不能恰好居中,可以稍稍偏左或者偏 ...
- 一、kafka 介绍 && kafka-client
一.kafka 介绍 1.1.kafka 介绍 Kafka 是一个分布式消息引擎与流处理平台,经常用做企业的消息总线.实时数据管道,有的还把它当做存储系统来使用. 早期 Kafka 的定位是一个高吞吐 ...
- 2个线程A-B-A-B或者B-A-B-A循环输出
代码: /** * 两个线程循环打印输出a-b-a-b */ public class AandBforTOthread { private static Object o = new Object( ...
- 如何安装 Sublime text 编辑器相关的插件
Sublime是一个伟大的编辑器,具有可靠的基础功能,使编写代码变得愉快.您可以安装一个包管理器,以便于安装插件和添加新功能. 为什么使用包管理器(package manager) 包管理器可以方便地 ...
- (六)MySQL数据、库、表的管理
目录 数据的管理 库的管理 表的管理 数据的管理 一.数据插入语句 1.语法: INSERT INTO 表名(列名,...) VALUES(值1,...); 2.案例:在beauty表中添加一条信息( ...