码迷,mamicode.com
首页 > 其他好文 > 详细

luogu P2607 [ZJOI2008] 骑士 树dp

时间:2018-11-03 23:06:48      阅读:126      评论:0      收藏:0      [点我收藏+]

标签:time   ati   memset   cto   width   class   space   math   size   

传送门

又一个没有上司的舞会

这个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 }
View Code

luogu P2607 [ZJOI2008] 骑士 树dp

标签:time   ati   memset   cto   width   class   space   math   size   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!