【树形DP】BZOJ1040-[ZJOI2008]骑士
【题目大意】
有n个骑士,给出他们的能力值和最痛恨的一位骑士。选出一个骑士军团,使得军团内没有矛盾的两人(不存在一个骑士与他最痛恨的人一同被选入骑士军团的情况),并且,使得这支骑士军团最具有战斗力,求战斗力的最大值。
【思路】
首先yy一下,可以知道这是一个基环森林。我们可以用以下方法:
首先在每一棵基环树的环上任意找到一条边(用dfs来实现),记它的两个端点为u和v。然后删掉这条边(我这里用的方法是记录u,v在对方容器中的位置,并在后续操作中忽略这条边)。由于u和v不能同时取,在删掉u和v之间的边后存在以下两种情况:
令g[i]为不取i时i及其子树的最大战斗力总和,f[i]则表示取i。
(1)u不取,v任意。则以u为根进行树形DP,结果为g[u];
(2)v不取,u任意。则以v为根进行树形DP,结果为g[v]。
然后ans+max(g[u],g[v])。
树形DP的过程非常地常规,就不赘述了 。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int MAXN=+;
typedef long long ll;
vector<int> E[MAXN];
int n,power[MAXN],hate[MAXN];
int vis[MAXN];
int U,V;
ll g[MAXN],f[MAXN]; void addedge(int u,int v)
{
E[u].push_back(v);
E[v].push_back(u);
} void dfs(int u,int fr)
{
vis[u]=;
for (int i=;i<E[u].size();i++)
{
int to=E[u][i];
if (to!=fr)
{
if (!vis[to]) dfs(to,u);
else
{
vis[to]=;
U=u;V=to;
return;
}
}
}
} void TreeDP(int u,int fr,int rt,int ban)
{
vis[u]=;
f[u]=power[u];
g[u]=;
for (int i=;i<E[u].size();i++)
{
int to=E[u][i];
if (u==rt && i==ban) continue;
if (to!=fr && to!=rt)
{
TreeDP(to,u,rt,ban);
f[u]+=g[to];
g[u]+=max(g[to],f[to]);
}
}
} void init()
{
scanf("%d",&n);
for (int i=;i<=n;i++)
{
scanf("%d%d",&power[i],&hate[i]);
addedge(i,hate[i]);
}
} void get_ans()
{
memset(vis,,sizeof(vis));
ll ans=;
for (int i=;i<=n;i++)
if (!vis[i])
{
dfs(i,-);
int banu,banv;
for (int i=;i<E[U].size();i++) if (E[U][i]==V)
{
banu=i;
break;
}
for (int i=;i<E[V].size();i++) if (E[V][i]==U)
{
banv=i;
break;
} TreeDP(U,-,U,banu);
ll uans=g[U]; TreeDP(V,-,V,banv);
ll vans=g[V];
ans+=max(uans,vans);
}
cout<<ans<<endl;
} int main()
{
init();
get_ans();
return ;
}
【树形DP】BZOJ1040-[ZJOI2008]骑士的更多相关文章
- 初涉基环外向树dp&&bzoj1040: [ZJOI2008]骑士
基环外向树dp竟然如此简单…… Description Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发 ...
- 【树形DP】ZJOI2008 骑士
题目内容 洛谷链接 有\(n\)位骑士,每个人的战力可能不同,并且每一个人都有且仅有一个憎恨的人,互相憎恨的人不能在同一队中. 求组合为一个骑士队的最大战斗力. PS:可以去看看题目背景学学历史(雾) ...
- 【环套树+树形dp】Bzoj1040 [ZJOI2008] 骑士
Description Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火 ...
- [BZOJ1040][ZJOI2008]骑士(树形DP)
对于一个联通块内,有且只有一个环,即n个点n条边 那么找到那个环,然后任意断一条边,这个联通块就变成一棵树了,然后做树形DP就行了 对于断的边要记录下来DP时特判 Code #include < ...
- [bzoj1040][ZJOI2008]骑士_树形dp_基环树_并查集
骑士 bzoj-1040 ZJOI-2008 题目大意:n个骑士,每个骑士有权值val和一个讨厌的骑士.如果一个骑士讨厌另一个骑士那么他们将不会一起出战.问出战的骑士最大atk是多少. 注释:$1\l ...
- BZOJ1040: [ZJOI2008]骑士(奇环树,DP)
题目: 1040: [ZJOI2008]骑士 解析: 假设骑士\(u\)讨厌骑士\(v\),我们在\(u\),\(v\)之间连一条边,这样我们就得到了一个奇环树(奇环森林),既然是一颗奇环树,我们就先 ...
- BZOJ1040 [ZJOI2008]骑士 基环树林(环套树) 树形动态规划
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题意概括 有n个人,每一个人有一个最恨的人. 并且,每一个人有一个权值. 一个人不可以和他最恨的人同时被选中. 现在请你求出在 ...
- [BZOJ1040][ZJOI2008]骑士(环套树dp)
1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5816 Solved: 2263[Submit][Status ...
- [BZOJ1040][ZJOI2008]骑士 基环树DP
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1040 题目给出了$n$个点和$n$条无向边,即一棵基环树或者基环树森林. 如果题目给的关系 ...
- BZOJ1040: [ZJOI2008]骑士 树套环DP
题意:一个图n个点n条边保证点能互相到达,ab有边意味着ab互相厌恶,求一个集合,使得集合里元素最多而且没有人互相厌恶 删去环上一条边树形dp,比如删掉的边连着a,b,那么先dp出不选a的最大值,再d ...
随机推荐
- $this->success()传值不完整
public function manager_doExport() { $search=$_POST['search']; //前台输入2017-12-1,即,$search['starttime' ...
- 【洛谷P2015】二叉苹果树
题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...
- Travelling(HDU3001+状压dp+三进制+最短路)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题目: 题意:n个城市,m条边,每条边都有一个权值,问你经过所有的城市且每条边通过次数不超过两次 ...
- NYOJ 1022 合纵连横 (并查集)
题目链接 描述 乱世天下,诸侯割据.每个诸侯王都有一片自己的领土.但是不是所有的诸侯王都是安分守己的,实力强大的诸侯国会设法吞并那些实力弱的,让自己的领土面积不断扩大.而实力弱的诸侯王为了不让自己的领 ...
- pycharm设置字体大小
pycharm 是很好的一个IDE,在windows下,和macOS下,都能很好的运行.唯一缺点是启动慢. 默认字体太小,在mac下,需要瞪大24K氪金狗眼才能看清. 为了保护好眼睛,我们需要把字体调 ...
- makefile里PHONY的相关介绍
Phony Targets PHONY 目标并非实际的文件名:只是在显式请求时执行命令的名字.有两种理由需要使用PHONY 目标:避免和同名文件冲突,改善性能. 如果编写一个规则,并不产生目标文件 ...
- PXC加入新节点避免SST时grastate.dat文件内容的修改问题
PXC加入新节点避免SST时grastate.dat文件内容的修改问题 在主从同步完成并关闭实例后,需要修改grastate.dat中的seqno:到底应该填已经执行过最后的XID号(Executed ...
- [ python ] 全局和局部作用域变量的引用
全局与局部变量的引用 (a)locals(b)globals 这里还需要在补充2个关键字一起比较学习,关键字:(c)nonlocal(d)global locals 和 globals locals: ...
- 产生随机数 random
int rand(void); 返回 0 ------- RAND_MAX 之间的一个 int 类型整数,该函数为非线程安全函数.并且生成随机数的性能不是很好,已经不推荐使用. void ...
- C++面试总结
1.多态 C++多态分两种--静态和动态,其中静态联编支持的多态称为编译时多态,包括重载和模板:动态联编支持的多态称为运行时多态,包括 继承和虚函数实现. 多态主要是由虚函数实现的,虚函数 ...