luogu P2607 [ZJOI2008] 骑士 树dp

传送门

又一个没有上司的舞会

这个dp有环 妈妈怎么办啊

要不...环上随便断一条边?

然后最后选的时候分别取两个根节点不选的情况的最大值

几个要点:

1.图可能是多个环套树 要循环走完

2.不能只记录顶点 因为如果有重边的话会把二元环筛掉

3.位运算优先级... 要写成(i^1)==cntline

Time cost inf

这题从上周就开始D

一度放弃 今天想整一下以前做过的所有题然后就

就写出来啦!!(开心)

Code:

(边界写的比较奇怪 是Debug的时候被吓怕了)

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<vector>
 6 #define ms(a,b) memset(a,b,sizeof a)
 7 #define inf 2147483647
 8 #define rep(i,a,n) for(int i = a;i <= n;i++)
 9 #define per(i,n,a) for(int i = n;i >= a;i--)
10 using namespace std;
11 typedef long long ll;
12 int read() {
13     int as = 0,fu = 1;
14     char c = getchar();
15     while(c<‘0‘||c>‘9‘) {
16         if(c == ‘-‘) fu = -1;
17         c = getchar();
18     }
19     while(c<=‘9‘&&c>=‘0‘) {
20         as = as * 10 + c - ‘0‘;
21         c = getchar();
22     }
23     return as * fu;
24 }
25 const int N = 1000005;
26 //head
27 int n;
28 int head[N],nxt[N<<1],mo[N<<1],cnt = -1;
29 void _add(int x,int y) {
30     mo[++cnt] = y;
31     nxt[cnt] = head[x];
32     head[x] = cnt;
33 }
34 void add(int x,int y) {if(x^y)_add(x,y),_add(y,x);}
35
36 int rt1,rt2,Cntline;
37 bool vis[N];
38 void dfs(int x,int f) {
39     vis[x] = 1;
40     for(int i = head[x];~i;i = nxt[i]) {
41         int sn = mo[i];
42         if(sn == f) continue;
43         if(!vis[sn]) dfs(sn,x);
44         else {
45             rt1 = x,rt2 = sn;
46             Cntline = i;
47         }
48     }
49 }
50
51 int v[N];
52 ll dp[N][2];
53 void Dp(int x,int f) {
54     dp[x][0] = 0,dp[x][1] = v[x];
55     for(int i = head[x];~i;i = nxt[i]) {
56         int sn = mo[i];
57         if(sn == f) continue;
58         if(i == Cntline || ((i ^ 1) == Cntline)) continue;
59         // printf("%d->%d\n",x,sn);
60         Dp(sn,x);
61         dp[x][0] += max(dp[sn][0],dp[sn][1]);
62         dp[x][1] += dp[sn][0];
63     }
64 }
65
66 int main() {
67     ms(head,-1);
68     n = read();
69     rep(i,1,n) {
70         v[i] = read();
71         add(i,read());
72     }
73     ll ans = 0,maxx;
74     rep(i,1,n) {
75         maxx = 0;
76         if(vis[i]) continue;
77         rt1 = rt2 = Cntline = -2;
78         dfs(i,-1);
79         // printf("%d %d %d\n",rt1,rt2,Cntline);
80         Dp(rt1,rt1),maxx = dp[rt1][0];
81         // printf("#%d\n",maxx);
82         Dp(rt2,rt2),maxx = max(maxx,dp[rt2][0]);
83         // printf("#%d\n",maxx);
84         ans += maxx;
85     }
86     printf("%lld\n",ans);
87     return 0;
88 }

原文地址:https://www.cnblogs.com/yuyanjiaB/p/9902212.html

时间: 2024-07-30 22:30:12

luogu P2607 [ZJOI2008] 骑士 树dp的相关文章

BZOJ 1040: [ZJOI2008]骑士( 树形dp )

这是一个森林中, 每棵树上都有一个环...每棵树单独处理, 找出环上任意一条边断开, 限制一下这条边两端点的情况, 然后就可以树dp了.. ------------------------------------------------------------------------ #include<cstdio> #include<algorithm> #include<cstring> #include<cctype> using namespace

【BZOJ1040】[ZJOI2008]骑士 树形DP

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

luogu P2700 逐个击破 树dp

传送门 好题啊 给定边权树 求隔离所有指定点的最小花费 考虑树dp的话 自然想到 f[x]表示子树内处理完从根节点出发没有敌人的最小花费 g[x]表示子树内处理完从根节点出发仍有敌人的最小花费 这个时候仍然合法() 又显然根节点是否有敌人是有影响的 所以分类讨论 首先子树没有敌人不用考虑 I. 根节点有敌人的话 f[x]就是inf g[x]直接取f[v]和g[v]+cst[i]最小值 表示是否切x->v这条边 II. 如果根节点没有 那么g[x]维护的就是选择一个花费最小的儿子切 而这样的花费就

P2607 [ZJOI2008]骑士

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

luogu P1270 &quot;访问&quot;美术馆 树dp

传送门 比较奇怪的树形背包 首先需要处理读入的问题 这题史诗递归读入 然后递归读入就不用建图 这题特点是只有叶子有价值 所以背包就不太有用 坑点就是这个人进去还得出来... 而且不能把时间都用完(导致75) Time cost: 35min Code: 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<queue> 6

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

1040: [ZJOI2008]骑士 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5816  Solved: 2263[Submit][Status][Discuss] Description Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各 界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火绵延五百里,在和平环境 中安逸了数百年的Z国又怎能抵挡的住Y国的军队.于是人

[ZJOI2008]骑士(基环树,树形dp)

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

【bzoj1040】[ZJOI2008]骑士 并查集+基环树dp

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

【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唯一的区别是,标记边两端不