题面

这道题稍微想一想就会联想到树形DP的入门题:没有上司的舞会;

但是再想一想会发现这根本就不是一颗树,因为它比树多了一条边;

这时候我们引入一个新的概念:基环树;

顾名思义(??),基环树就是在一颗树上填一条边构成的一个图;基环树也叫环套树(明明更像树套环)。

我们在树上可以做的事情基本都可以在基环树上实现:比如树形DP

基环树的基本解题思路就是找到在环上的两个点:S,T;

分别以S,T为根来跑一边DP,这样把两次的答案进行处理就可以解决掉这道题;

那么怎样找环?我总结了几种不同的思路:

1.并查集找环:对于要加入的两个点如果已经在同一个区域内,那么他们一定在环上;

2.tarjan找环:对于一个点,如果dfn[v]<dfn[u],那么u和v就在一个环上;

3.dfs找环:其实和tarjan的基本思路一样,如果一个点的子节点v已经被经过,那么u和v就在一个环上;

#include <bits/stdc++.h>
#define int long long
using namespace std;
struct littlestar{
int to;
int nxt;
}star[2000010];
int head[2000010],cnt;
void add(int u,int v)
{
star[++cnt].to=v;
star[cnt].nxt=head[u];
head[u]=cnt;
}
int ha[1000010],fa[1000010];
int f[1000010],g[1000010],vis[1000010];
void dfs(int u,int goal)
{
vis[u]=1;
f[u]=ha[u];
for(int i=head[u];i;i=star[i].nxt){
int v=star[i].to;
if(v==goal){
f[v]=-999999999;
continue;
}
dfs(v,goal);
g[u]+=max(g[v],f[v]);
f[u]+=g[v];
}
}
int ans;
signed main()
{
int n; cin>>n;
for(register int i=1;i<=n;i++){
scanf("%d%d",&ha[i],&fa[i]);
add(fa[i],i);
}
for(register int i=1;i<=n;i++){
if(!vis[i]){
vis[i]=1;
int root=i;
while(!vis[fa[root]]){
root=fa[root];
vis[root]=1;
}
dfs(root,root);
int tmp=max(g[root],f[root]);
vis[root]=1;
memset(f,0,sizeof(f));
memset(g,0,sizeof(g));
root=fa[root];
dfs(root,root);
tmp=max(tmp,max(g[root],f[root]));
memset(f,0,sizeof(f));
memset(g,0,sizeof(g));
ans+=tmp;
}
}
cout<<ans;
}

然后可以双倍经验:洛谷 P1453 城市环路

#include <bits/stdc++.h>
using namespace std;
struct littlestar{
int to;
int nxt;
}star[200010];
int head[200010],cnt;
void add(int u,int v)
{
star[++cnt].to=v;
star[cnt].nxt=head[u];
head[u]=cnt;
}
int ha[100010],fa[100010];
double f[100010],g[100010];
void dfs(int u,int ff)
{
f[u]=ha[u];
g[u]=0;
for(int i=head[u];i;i=star[i].nxt){
int v=star[i].to;
if(v==ff){
continue;
}
dfs(v,u);
f[u]+=g[v];
g[u]+=max(g[v],f[v]);
}
}
inline int zhaobaba(int x)
{
if(fa[x]==x) return x;
return fa[x]=zhaobaba(fa[x]);
}
int S,T;
int main()
{
int n;
cin>>n;
for(register int i=1;i<=n;i++) scanf("%d",&ha[i]),fa[i]=i;
for(register int i=1;i<=n;i++){
int u,v;
scanf("%d%d",&u,&v);
++u;
++v;
if(zhaobaba(u)==zhaobaba(v)){
S=u;
T=v;
continue;
}
add(u,v);
add(v,u);
fa[zhaobaba(v)]=zhaobaba(u);
}
double ans=0,k;
scanf("%lf",&k);
dfs(S,0);
ans=g[S];
dfs(T,0);
ans=max(ans,g[T]);
printf("%.1lf",ans*k);
}

[ZJOI2008]骑士 题解的更多相关文章

  1. Bzoj 1040 [ZJOI2008]骑士 题解

    1040: [ZJOI2008]骑士 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5368  Solved: 2044[Submit][Status ...

  2. P2607[ZJOI2008] 骑士 题解

    题目 Z 国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的 Y 国发动了一场针对 Z 国的侵略战争.战火绵延五 ...

  3. BZOJ1040:[ZJOI2008]骑士——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=1040 题面大意:n个人有一个价值和一个最恨的人,现在组出一个队伍使得价值最大且没有仇恨关系. ——— ...

  4. [ZJOI2008]骑士

    [ZJOI2008]骑士 标签: DP 题目链接 题解 把边看成无向的. 其实就是求这个东西的最大独立集. 但是这不是树,怎么求呢? 其实还是一样的求法. 对于每一个连通块.最多有这个联通块的大小数目 ...

  5. [BZOJ 1040][ZJOI2008]骑士

    1040: [ZJOI2008]骑士 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5403  Solved: 2060[Submit][Status ...

  6. 【BZOJ1040】[ZJOI2008]骑士 树形DP

    [BZOJ1040][ZJOI2008]骑士 Description Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情 ...

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

    [ZJOI2008]骑士 题目描述 Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的 ...

  8. 「树形DP」洛谷P2607 [ZJOI2008]骑士

    P2607 [ZJOI2008]骑士 题面: 题目描述 Z 国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的 ...

  9. BZOJ 1040: [ZJOI2008]骑士 基环加外向树

    1040: [ZJOI2008]骑士 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1190  Solved: 465[Submit][Status] ...

随机推荐

  1. BZOJ 2870: 最长道路tree 树的直径+并查集

    挺好的一道题. 把所有点都离线下来,一个个往里加入就行了. #include <cstdio> #include <algorithm> #define N 100003 #d ...

  2. luoguP3353 在你窗外闪耀的星星

    P3353 在你窗外闪耀的星星 题目描述 飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年前,在美丽的集美中学,从我看到你微笑着走出教室,你将头向 ...

  3. Springboot入门实战, 使用@Value

    今天开始最简单的Springboot应用 entity.Book package com.draymonder.amor.entity; import java.util.List; import o ...

  4. sh_10_字典基本使用

    sh_10_字典基本使用 xiaoming_dict = {"name": "小明"} # 1. 取值 print(xiaoming_dict["na ...

  5. sh_06_元组基本使用

    sh_06_元组基本使用 info_tuple = ("zhangsan", 18, 1.75, "zhangsan") # 1. 取值和取索引 print(i ...

  6. 前端js图片上传

    前端js图片上传,原理用input type="file"获取图片然后把图片转换成base64编码传到后台. 图片上传 <!DOCTYPE html><html& ...

  7. The 5 types of programmers

    from: http://stevenbenner.com/2010/07/the-5-types-of-programmers/ps: 评论也很精彩 In my code journeys and ...

  8. DeepFaceLab参数详解之FPS与Image format

    DeepFaceLab参数详解之FPS与Image format , 本文讲解两个非常简单的参数,也是大家玩这个软件最先接触到的.参数虽然非常的简单,但是非常有用,适当调整可以为你节省大量硬盘空间,大 ...

  9. Ubuntu:Unable to locate package ***

    在Ubuntu 上使用apt-get 安装包时遇到  Unable to locate package 的信息 解决方案: 更细apt-get然后重新安装 #sudo apt-get update   ...

  10. PRISM 4 - RegisterViewWithRegion & Custom Export Attributes

    5down votefavorite   I am using Prism 4 with MEF Extensions and the MVVM pattern. During initializat ...