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

ZJOI2008 骑士 【基环树】

时间:2018-10-28 22:00:23      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:img   get   bit   strong   clu   src   style   题意   closed   

ZJOI2008 骑士

 

题意见链接。。。

 

本题较为经典,值得一做。基环外向树练手好题。

如果不考虑环的情况,则就是普通树形DP,f[i][0/1] 表示这个点取或不取。

对于此题一棵树只能出现一个环,我们任意删去环上的一条边,即可转环为树。

对于 (u,v)

1:u 不取,则以 u 为根DP。

2:v 不取,则以 v 为根DP。

不需要考虑两个点的分别情况,DP的时候考虑在内。

 

判环我用并查集。

 

贴代码:

 

技术分享图片
 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 int n,m,cnt;
 5 const int N=1000005;
 6 int fa[N],to[N<<1],nxt[N<<1],hea[N],ra[N],rb[N];
 7 ll f[N],g[N],v[N],ans;
 8 inline int getf(int x)
 9 {
10     return fa[x]==x?x:fa[x]=getf(fa[x]);
11 }
12 inline void dfs(int x,int fat)
13 {
14     f[x]=v[x],g[x]=0;
15     for (int i=hea[x]; i; i=nxt[i])
16     {
17         int y=to[i];
18         if (y==fat) continue;
19         dfs(y,x);
20         g[x]+=max(f[y],g[y]);
21         f[x]+=g[y];
22     }
23 }
24 inline void add(int x,int y)
25 {
26     to[++cnt]=y,nxt[cnt]=hea[x],hea[x]=cnt;
27 }
28 int main()
29 {
30     scanf("%d",&n);
31     for (int i=1; i<=n; ++i) fa[i]=i;
32     memset(hea,-1,sizeof(hea));
33     int b;
34     for (int i=1; i<=n; ++i)
35     {
36         scanf("%lld%d",&v[i],&b);
37         if (getf(i)!=getf(b))
38         {
39             add(i,b); add(b,i);
40             fa[fa[i]]=fa[b];
41         }
42         else ra[++m]=i,rb[m]=b;
43     }
44     ll t;
45     for (int i=1; i<=m; ++i)
46     {
47         dfs(ra[i],0); t=g[ra[i]];
48         dfs(rb[i],0); t=max(t,g[rb[i]]);
49         ans+=t;
50     }
51     printf("%lld\n",ans);
52     return 0;
53 }
View Code

 

 

 

 

 

fighting fighting fighting

 

ZJOI2008 骑士 【基环树】

标签:img   get   bit   strong   clu   src   style   题意   closed   

原文地址:https://www.cnblogs.com/Frank-King/p/9866985.html

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