[BZOJ1040][ZJOI2008]骑士(环套树dp)

1040: [ZJOI2008]骑士

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 5816  Solved: 2263
[Submit][Status][Discuss]

Description

  Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英。他们劫富济贫,惩恶扬善,受到社会各

界的赞扬。最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争。战火绵延五百里,在和平环境

中安逸了数百年的Z国又怎能抵挡的住Y国的军队。于是人们把所有的希望都寄托在了骑士团的身上,就像期待有一

个真龙天子的降生,带领正义打败邪恶。骑士团是肯定具有打败邪恶势力的能力的,但是骑士们互相之间往往有一

些矛盾。每个骑士都有且仅有一个自己最厌恶的骑士(当然不是他自己),他是绝对不会与自己最厌恶的人一同出

征的。战火绵延,人民生灵涂炭,组织起一个骑士军团加入战斗刻不容缓!国王交给了你一个艰巨的任务,从所有

的骑士中选出一个骑士军团,使得军团内没有矛盾的两人(不存在一个骑士与他最痛恨的人一同被选入骑士军团的

情况),并且,使得这支骑士军团最具有战斗力。为了描述战斗力,我们将骑士按照1至N编号,给每名骑士一个战

斗力的估计,一个军团的战斗力为所有骑士的战斗力总和。

Input

  第一行包含一个正整数N,描述骑士团的人数。接下来N行,每行两个正整数,按顺序描述每一名骑士的战斗力

和他最痛恨的骑士。

Output

  应包含一行,包含一个整数,表示你所选出的骑士军团的战斗力。

Sample Input

3

10 2

20 3

30 1

Sample Output

30

HINT

N ≤ 1 000 000,每名骑士的战斗力都是不大于 1 000 000的正整数。

Source

[Submit][Status][Discuss]

每个点有且仅有一个出边,说明每个连通分量(有向连通)都是有且仅有一个环,以及环边的树(树根必定在环上),这就是基环外向树问题。

感觉有点像仙人球的超弱化版?直接对一个每遍历过的点,找到所在的连通分量的环,然后

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define rep(i,l,r) for (int i=l; i<=r; i++)
 4 #define For(i,x) for (int i=h[x],k; i; i=nxt[i])
 5 typedef long long ll;
 6 using namespace std;
 7
 8 const int N=2000100,inf=1000000000;
 9 int n,cnt,rt,fa[N],val[N],vis[N],to[N],nxt[N],h[N];
10 ll f[N][2],ans;
11 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
12
13 void dfs(int x){
14     vis[x]=1; f[x][0]=0; f[x][1]=val[x];
15     For(i,x) if ((k=to[i])!=rt)
16         dfs(k),f[x][0]+=max(f[k][1],f[k][0]),f[x][1]+=f[k][0];
17     else f[k][1]=-inf;
18 }
19
20 void find(int x){
21     vis[x]=1; rt=x;
22     while (!vis[fa[rt]]) rt=fa[rt],vis[rt]=1;
23     dfs(rt); ll t=max(f[rt][0],f[rt][1]);
24     vis[rt]=1; rt=fa[rt]; dfs(rt); ans+=max(t,max(f[rt][0],f[rt][1]));
25 }
26
27 int main(){
28     freopen("P2607.in","r",stdin);
29     freopen("P2607.out","w",stdout);
30     scanf("%d",&n);
31     rep(i,1,n) scanf("%d",&val[i]),scanf("%d",&fa[i]),add(fa[i],i);
32     rep(i,1,n) if (!vis[i]) find(i);
33     printf("%lld\n",ans);
34     return 0;
35 }

原文地址:https://www.cnblogs.com/HocRiser/p/8459850.html

时间: 2024-08-27 09:13:25

[BZOJ1040][ZJOI2008]骑士(环套树dp)的相关文章

【BZOJ】1040: [ZJOI2008]骑士 环套树DP

[题意]给定n个人的ai和bi,表示第i个人能力值为ai且不能和bi同时选择,求能力值和最大的选择方案.n<=10^6. [算法]环套树DP(基环树) [题解]n个点n条边--基环森林(若干环套树子图). 若原图是树,经典DP做法:f[i][0/1]表示i点选或不选的最大能力值和,则f[i][0]=Σmax{f[j][0],f[j][1]},f[i][1]=Σf[j][0]+a[i],j=son[i]. 找环:dfs到访问过的点,标记环上的一条边. 破环:和普通树上DP唯一的区别是,标记边两端不

BZOJ 1040 骑士(环套树DP)

如果m=n-1,显然这就是一个经典的树形dp. 现在是m=n,这是一个环套树森林,破掉这个环后,就成了一个树,那么这条破开的边连接的两个顶点不能同时选择.我们可以对这两个点进行两次树形DP根不选的情况. 那么答案就是每个森林的max()之和. # include <cstdio> # include <cstring> # include <cstdlib> # include <iostream> # include <vector> # in

bzoj1040(ZJOI2008)骑士——基环树

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1040 基环树的模板. 套路就是把环断开,先把一端作为根节点,强制不选:再把另一端作为根节点,强制不选. 人家的这个判断环的方法真好!还顺便没有连上环的那条边,省下了在函数里判断. 别忘了有多棵基环树! #include<iostream> #include<cstdio> #include<cstring> #define ll long long using n

luogu2607/bzoj1040 [ZJOI2008]骑士 (基环树形dp)

N个点,每个点发出一条边,那么这个图的形状一定是一个基环树森林(如果有重边就会出现森林) 那我做f[0][x]和f[1][x]分别表示对于x子树,x这个点选还是不选所带来的最大价值 然后就变成了这好几个环上不能选相邻的点,最大的价值和 我们把这个环从N到1处断开,然后钦定一下1选还是不选,统计一下答案就可以了. 1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define ll long long 4 using na

BZOJ1040:骑士(基环树DP)

Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火绵延五百里,在和平环境中安逸了数百年的Z国又怎能抵挡的住Y国的军队.于是人们把所有的希望都寄托在了骑士团的身上,就像期待有一个真龙天子的降生,带领正义打败邪恶.骑士团是肯定具有打败邪恶势力的能力的,但是骑士们互相之间往往有一些矛盾.每个骑士都有且仅有一个自己最厌恶的骑士(当然不是他自己),他是绝对不会与自己最厌恶的人一同出

Bzoj1040 [ZJOI2008]骑士

Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4496  Solved: 1721 Description Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火绵延五百里,在和平环境中安逸了数百年的Z国又怎能抵挡的住Y国的军队.于是人们把所有的希望都寄托在了骑士团的身上,就像期待有一个真龙天子的降生,带领正义打败邪恶.骑士团

【环套树+树形dp】Bzoj1040 [ZJOI2008] 骑士

Description Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火绵延五百里,在和平环境中安逸了数百年的Z国又怎能抵挡的住Y国的军队.于是人们把所有的希望都寄托在了骑士团的身上,就像期待有一个真龙天子的降生,带领正义打败邪恶.骑士团是肯定具有打败邪恶势力的能力的,但是骑士们互相之间往往有一些矛盾.每个骑士都有且仅有一个自己最厌恶的骑士(当然不是他自己),他是绝对不

BZOJ_1040_[ZJOI2008]骑士_树形DP

题意: Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各 界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火绵延五百里,在和平环境 中安逸了数百年的Z国又怎能抵挡的住Y国的军队.于是人们把所有的希望都寄托在了骑士团的身上,就像期待有一 个真龙天子的降生,带领正义打败邪恶.骑士团是肯定具有打败邪恶势力的能力的,但是骑士们互相之间往往有一 些矛盾.每个骑士都有且仅有一个自己最厌恶的骑士(当然不是他自己),他是绝对不会与自己

【距离GDKOI:44天&amp;GDOI:107天】【BZOJ1040】[ZJOI2008] 骑士

其实已经准备退役了,但GDOI之前还是会继续学下去的!!当成兴趣在学,已经对竞赛失去信心了的样子,我还是回去跪跪文化课吧QAQ 第一道环套树DP...其实思想挺简单的,就把环拆开,分类处理.若拆成开的两个点是u,v,dp[i,0..1]分别表示第i位骑士不选和选 (1) 不选u,v点随意    (2)u随意,v点不选... 分类dp处理即可 1 const maxn=1000419; 2 type 3 edgetype=record 4 toward,next:longint; 5 end; 6