[ZJOI2008]骑士(基环树,树形dp)
[ZJOI2008]骑士
题目描述
Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英。他们劫富济贫,惩恶扬善,受到社会各界的赞扬。
最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争。战火绵延五百里,在和平环境中安逸了数百年的Z国又怎能抵挡的住Y国的军队。于是人们把所有的希望都寄托在了骑士团的身上,就像期待有一个真龙天子的降生,带领正义打败邪恶。
骑士团是肯定具有打败邪恶势力的能力的,但是骑士们互相之间往往有一些矛盾。每个骑士都有且仅有一个自己最厌恶的骑士(当然不是他自己),他是绝对不会与自己最厌恶的人一同出征的。
战火绵延,人民生灵涂炭,组织起一个骑士军团加入战斗刻不容缓!国王交给了你一个艰巨的任务,从所有的骑士中选出一个骑士军团,使得军团内没有矛盾的两人(不存在一个骑士与他最痛恨的人一同被选入骑士军团的情况),并且,使得这支骑士军团最具有战斗力。
为了描述战斗力,我们将骑士按照1至N编号,给每名骑士一个战斗力的估计,一个军团的战斗力为所有骑士的战斗力总和。
输入输出格式
输入格式:
输入文件knight.in第一行包含一个正整数N,描述骑士团的人数。
接下来N行,每行两个正整数,按顺序描述每一名骑士的战斗力和他最痛恨的骑士。
输出格式:
输出文件knight.out应包含一行,包含一个整数,表示你所选出的骑士军团的战斗力。
输入输出样例
输入样例#1: 复制
3
10 2
20 3
30 1
输出样例#1: 复制
30
说明
对于30%的测试数据,满足N ≤ 10;
对于60%的测试数据,满足N ≤ 100;
对于80%的测试数据,满足N ≤ 10 000。
对于100%的测试数据,满足N ≤ 1 000 000,每名骑士的战斗力都是不大于 1 000 000的正整数。
题解
第一眼看题。
\(woc\),为什么没有上司的舞会紫了。
码了码了水题目。
怎么有\(n\)条边。
原来是基环树\(Orz\)。
还是基环树森林(题目不保证联通)。
于是决定做一做秒开查题解
对于一颗基环树,我们能够确定的是如果在环上断开一条边。
那么这就是一颗正常的树了。
那么怎么断环呢。假设是根到随机一个点多了一条边。
就是根与那个点只能选一个。
其他的没有变化。
我们考虑随机断掉一条边。
判环是否形成用并查集维护就好了,不用强行遍历。
对于边连接的两个点做最简单的树形\(dp\)
\(f[i][0]\)表示不选当前节点
\(f[i][1]\)表示选当前节点
那么我们每次就判断这两个点那个价值大。
注意因为这两个点只能选一个,所以要强制不选一个点。
也就是说每次统计的是\(f[i][0]\)的贡献。
题解
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#define ll long long
using namespace std;
const int N=1000001;
struct node{
int to,nex;
}e[N<<1];
ll f[N][2],fa[N],ans;
ll n,m,l[N],r[N],vi[N];
ll num,head[N];
ll read(){
ll x=0,w=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*w;
}
void add(int from,int to){
num++;
e[num].to=to;
e[num].nex=head[from];
head[from]=num;
}
int find(int x){
return x==fa[x]?x:fa[x]=find(fa[x]);
}
void dfs(int x,int fa){
f[x][1]=vi[x];f[x][0]=0;
for(int i=head[x];i;i=e[i].nex){
int v=e[i].to;
if(v==fa)continue;
dfs(v,x);
f[x][0]+=max(f[v][0],f[v][1]);
f[x][1]+=f[v][0];
}
}
int main(){
n=read();
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=n;i++){
vi[i]=read();
int x=read();
if(find(i)==find(x))l[++m]=i,r[m]=x;
else {
fa[find(x)]=fa[find(i)];
add(i,x);add(x,i);
}
}
for(int i=1;i<=m;i++){
ll tmp=0;
dfs(l[i],0);tmp=f[l[i]][0];
dfs(r[i],0);tmp=max(f[r[i]][0],tmp);
ans+=tmp;
}
printf("%lld\n",ans);
return 0;
}
[ZJOI2008]骑士(基环树,树形dp)的更多相关文章
- BZOJ 1040 [ZJOI2008]骑士 (基环树+树形DP)
<题目链接> 题目大意: Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的 ...
- 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】
没考虑可以连着两个不选--直接染色了 实际上是基环森林,对于每棵基环树,dfs找出一个环边,然后断掉这条边,分别对这条边的两端点做一边treedp,取max加进答案里 treedp是设f[u]为选u点 ...
- [ZJOI2008] 骑士 - 基环树dp
一类基环树dp都是这个套路吧 随便拆掉环上的一条边 然后跑树形dp,设\(f[i][0/1]\)表示以第\(i\)个人为根的子树,第\(i\)个人选或不选,能收获的最大值 以断点\(u,v\)为根分别 ...
- P2607 [ZJOI2008]骑士 基环树,树dp;
P2607 [ZJOI2008]骑士 本题本质上就是树dp,和没有上司的舞会差不多,只不过多了一个对基环树的处理. #include<iostream> #include<cstri ...
- 骑士 HYSBZ - 1040(基环树+树形dp)
Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火绵延五百里,在和平环境中 ...
- [BZOJ1040][ZJOI2008]骑士 基环树DP
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1040 题目给出了$n$个点和$n$条无向边,即一棵基环树或者基环树森林. 如果题目给的关系 ...
- BZOJ 1040 ZJOI 2008 骑士 基环树林+树形DP
题目大意:有一些骑士.他们每个人都有一个权值.可是因为一些问题,每个骑士都特别讨厌还有一个骑士.所以不能把他们安排在一起.求这些骑士所组成的编队的最大权值和是多少. 思路:首先貌似是有向图的样子,可是 ...
随机推荐
- python位操作(进制)与ascii
位操作符 位操作的操作符与python的set的操作符一样.与C语言中的位操作符也是一样的. a = 60 #60的二进制为 0011 1100b = 13 #13的二进制为 00001101 c = ...
- Django REST Framework 数码宝贝 - 3步进化 - 混合类 -->
读了我这篇博客, 你会刷新对面对对象的认知, 之前的面对对象都是LJ~~~ 表结构 class Publisher(models.Model): name = models.CharField(max ...
- 如何使用JAVA请求HTTPS
JDK对应的TLS版本(仅供参考) 1.写一个SSLClient类,继承至HttpClient import java.security.cert.CertificateException; impo ...
- SQL SERVER-identity | @@identity | scope_identity
主键自增 IDENTITY(1,1),MS SQL Server 使用 IDENTITY 关键字来执行 auto-increment 任务. 在上面的实例中,IDENTITY 的开始值是 1,每条新记 ...
- c/c++常见试题
- C中操作文件的几种模式
使用文件的方式共同拥有12种,以下给出了它们的符号和意义. 文件打开方式 意义 rt 仅仅读打开一个文本文件.仅仅同意读数据 wt 仅仅写打开或建立一个文本文件,仅仅同意写数据 at 追 ...
- X-射线:探索原子世界的利器
请看下图: 上图是在现代量子力学意义上的氦(Helium)原子图像,原子像是一个黑乎乎的"小云团"(电子云包围着原子核).原子的半径大约仅仅有1埃. "埃"的符 ...
- Visual C++文件后缀名释义
[1] .APS:存放二进制资源的资源辅助中间文件(可加快资源装载速度). [2] .BMP:位图资源文件. [3] .BSC:浏览信息文件.由浏览信息维护工具(BSCMAKE)从原始浏览信息文件(. ...
- linux使用windows中编辑的文件,格式问题
参考:https://blog.csdn.net/yongan1006/article/details/8142527 运行脚本时出现了这样一个错误,打开之后并没有找到所谓的^M,查了之后才知道原来是 ...
- python部分
读取骨骼数据相关的多个json,拼接到一起 # -- coding: utf-8 -- import os path = "./test" #文件夹目录 files= os.lis ...