题面

这道题稍微想一想就会联想到树形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. PHP大文件上传断点续传解决方案

    1.使用PHP的创始人 Rasmus Lerdorf 写的APC扩展模块来实现(http://pecl.php.net/package/apc) APC实现方法: 安装APC,参照官方文档安装,可以使 ...

  2. 暑假集训 #2 div1 I - Lada Priora 精度处理

    I - Lada Priora Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Sub ...

  3. SSH上传文件出现error

    如上图,因为我在SSH上的用户没有对Linux服务器的文件夹的修改权限,我在linux上把文件夹的权限改为可读可改,就可以了

  4. oracle性能诊断排查

    https://blog.csdn.net/qq_30553235/article/details/78809872 查看oracle用户权限: 1.查看不同用户的连接数 select usernam ...

  5. IDEA超实用快捷键

    1.查看某个方法在哪里被调用了 Ctrl+G 2.从Controller跳过接口快速进入到实现类的方法: Ctrl+T 3.快速打开:Generate Alt+Insert 4.生成包裹代码: Ctr ...

  6. python3使用ltp语言云

    text="我爱自然语言处理." text=str(text) #text=urllib.quote(text) text=urllib.parse.quote(text) def ...

  7. Windows监控——性能指标详解(转)

    http://blog.csdn.net/yiqin3399/article/details/51730106

  8. CentOS7 通过 YUM 升级 VIM8

    Run 就完了: rpm -Uvh http://mirror.ghettoforge.org/distributions/gf/gf-release-latest.gf.el7.noarch.rpm ...

  9. enumerable 可枚举 属性

    一个对象的可枚举属性会在for...in中被访问到 (或是类似的迭代方法, Object.keys() 如果一个属性不是可枚举的,循环会忽略这个属性 var obj = { key: 'val' }; ...

  10. Hibernate框架 初识 ORM概念

    Hibernate概述 Hibernate是一个ORM(对象关系映射)映射框架,它的核心思想就是在底层对JDBC进行了一次封装. 什么是框架 IT语境中的框架,特指为解决一个开放性问题而设计的具有一定 ...