题面

这道题稍微想一想就会联想到树形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. HTML5+CSS3制作无限滚动与文字跳动效果

    ㈠用HTML5+CSS3做无限滚动效果 ⑴逻辑分析 ⑵实践示例 前5张图片为所有图片显示区,假设总长度为1100px: 后面出现的五张图片为克隆区,只是将前面的图片拷贝了一份: 然后将前五张和后五张的 ...

  2. linux查看网关

    Linux下查看网关方法:route -n ip route show traceroute www.prudentwoo.com -s 100 第一行就是自己的默认网关 netstat -r mor ...

  3. Javascript兼容各浏览器的日期转换

    var date = new Date(Date.parse("2015-09-05".replace(/-/g,"/")));'2015-09-05'是无法被 ...

  4. maven项目创建4

    运行maven项目,首先要不最根项目添加到maven本地仓库,执行  项目-->右键-->Run as-->Maven install 注:创建war包项目,本地测试,创建index ...

  5. Link-Cut Tree(LCT) 教程

    目录 前置知识 介绍 Access FindRoot MakeRoot Split Link Cut 关于Splay中操作的一点说明: 模板 前置知识 请先对树链剖分和Splay有所了解.LCT基于树 ...

  6. css彩色(渐变)文字

    css彩色文字也称渐变文字 在张鑫旭博客首页看到这效果,就自己研究了一下. 实现方法加个背景然后在根据文本剪切,再把文本填充为透明色让之前设置的背景颜色显示出来即可. -webkit-backgrou ...

  7. Linux环境下TomCat使用指定JDK的版本

    服务器是web服务器,在上面安装了jdk1.7和jdk1.8.及多个tomcat应用,默认/etc/profile 配置的jdk1.7,大部分tomcat应用使用的也是jdk1.7, 但目前有一个新项 ...

  8. Java中的Unicode与码点

    Java中,可以用\uXXXX表示Unicode字符,例如String s = "\u00X1";XXXX必须为4位,因此码点为U+1D546的字符,需要用两个编码单元表示,例如S ...

  9. Linux上python3的安装和使用

    centos7默认是装有python的,咱们先看一下 #检查python版本 [root@oldboy_python ~ 17:23:54]#python -V Python 2.7.5 但是 pyt ...

  10. maven web项目中运行stucts2报404的解决方案

    从这篇文章看见的https://www.cnblogs.com/xxqxxq/p/5938821.html 1.将stucts.xml中所有<action>全部注释掉,重新运行 如果运行成 ...