P1453 城市环路

感觉基环树(or环套树)的题目一般都是找到树上的环,断掉一条边再进行树上的操作(如noip2018P5022 旅行)

双倍经验:P2607 [ZJOI2008]骑士

P1453和P2607这两题实际上就是基环树上的P1352 没有上司的舞会,用树形DP即可,但是因为有环,所以要先找到环再删一条边才能DP

至于树形DP就不多说了,毕竟是基环树,最主要的就是找环操作了,翻了翻题解,大概有下面几种方法:

一. 读入时判断

  1. 并查集 ,若两点在一个并查集中则记录下来,不连边不合并

  2. (不建议使用)bool记录点是否出现过,若读入时两点在之前都已出现了,则为环,不连边(BUG:本题数据较弱可过,但可能在一些数据中出错,看评论中有一组hack数据:5 1 2 3 4 5 0 1 2 3 2 4 0 2 3 4 9.0,答案为63.0,但这种找环方法会超时)

二、读入后判断

  1. 如本程序,dfs找环,找到时记录两点a,b或边编号e,dp时不仅要判断v!=fa,还应判断(u!=a || v!=b) && (u!=b || v!=a)或(e!=i && (e^1)!=i)(双向边)

  2. (不建议使用)连单向边u->v(注意要保证有有向环),记录fa[v]=u,从一个已存在的点开始不断找fa直到遇到走过的则找到了环。这种写法可以用在P2607(见这个题解),此题未必可行

while(!vis[fa[rt]]) rt=fa[rt],vis[rt]=1;//rt与fa[rt]连为了环

对于此题,找到环上两点a,b后,分别以a,b为根做两次树形DP,第一次取f[a][0],第二次取f[b][0](这样保证a与b虽相邻但不会同时被被取),取max(f[a][0],f[b][0])与K相乘即可

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define ll int //这个代码是在P2607的基础上修改的,所以直接把ll定义为int了
const int N=1e5+100;
int h[N],rt,rt2,n,cnt,val[N];
bool vis[N];
ll f[N][2],ans;
struct edge {
int v,h;
} e[N<<1];
inline void add(int u,int v) {
e[++cnt]=(edge) {
v,h[u]
},h[u]=cnt;
} void dp(int x,int fa) {
vis[x]=1,f[x][1]=val[x];
for (int i=h[x],v; i; i=e[i].h) {
v=e[i].v;
if ((x!=rt || v!=rt2) && (x!=rt2 || v!=rt) && v!=fa)
dp(v,x),
f[x][0]+=max(f[v][0],f[v][1]),
f[x][1]+=f[v][0];
}
} bool find(int x,int fa) { //dfs找环
vis[x]=1;
for(int i=h[x]; i; i=e[i].h)
if (e[i].v^fa)
if (vis[e[i].v]) {
rt=e[i].v,rt2=x; //找到了环,记录起端点(相当于切断i这条边)
return 1;
} else if (find(e[i].v,x)) return 1;
} void solve(int x) { //分别以两端点做树形DP
find(x,-1);
dp(rt,rt);
ll tmp=f[rt][0]; memset(f,0,sizeof f);
dp(rt2,rt2); ans=max(tmp,f[rt2][0]);
}
int main() {
scanf("%d",&n);
for (int i=0; i<n; i++) scanf("%d",&val[i]);
for (int i=1,x,y; i<=n; i++) scanf("%d%d",&x,&y),add(x,y),add(y,x);
solve(0); //注意若是森林需枚举1~n的点
double tmp;
scanf("%lf",&tmp);
printf("%.1lf",(double)ans*tmp);
}

题解 P1453 【城市环路】的更多相关文章

  1. BSOJ3760||洛谷P1453 城市环路 题解

    城市环路 Description 一座城市,往往会被人们划分为几个区域,例如住宅区.商业区.工业区等等.B市就被分为了以下的两个区域——城市中心和城市郊区.在着这两个区域的中间是一条围绕B市的环路,环 ...

  2. 洛谷 P1453 城市环路 ( 基环树树形dp )

    题目链接 题目背景 一座城市,往往会被人们划分为几个区域,例如住宅区.商业区.工业区等等.B市就被分为了以下的两个区域--城市中心和城市郊区.在着这两个区域的中间是一条围绕B市的环路,环路之内便是B市 ...

  3. P1453 城市环路

    题目背景 一座城市,往往会被人们划分为几个区域,例如住宅区.商业区.工业区等等.B市就被分为了以下的两个区域——城市中心和城市郊区.在着这两个区域的中间是一条围绕B市的环路,环路之内便是B市中心. 题 ...

  4. luogu P1453 城市环路

    题目描述 整个城市可以看做一个N个点,N条边的单圈图(保证图连通),唯一的环便是绕城的环路.保证环上任意两点有且只有2条路径互通.图中的其它部分皆隶属城市郊区. 现在,有一位名叫Jim的同学想在B市开 ...

  5. LUOGU P1453 城市环路(基环树+dp)

    传送门 解题思路 一道基环树上$dp$的题,这种题比较套路吧,首先第一遍$dfs$把环找出来,然后对于环上的每一个点都向它子树内做一次树形$dp$,$f[i][0/1]$表示到了$i$这个点选或不选的 ...

  6. [ZJOI2008]骑士 题解

    题面 这道题稍微想一想就会联想到树形DP的入门题:没有上司的舞会: 但是再想一想会发现这根本就不是一颗树,因为它比树多了一条边: 这时候我们引入一个新的概念:基环树: 顾名思义(??),基环树就是在一 ...

  7. 2021record

    2021-10-14 P2577 [ZJOI2004]午餐 2021-10-13 CF815C Karen and Supermarket(小小紫题,可笑可笑) P6748 『MdOI R3』Fall ...

  8. 2018 AI产业界大盘点

    2018  AI产业界大盘点 大事件盘点 “ 1.24——Facebook人工智能部门负责人Yann LeCun宣布卸任 Facebook人工智能研究部门(FAIR)的负责人Yann LeCun宣布卸 ...

  9. 绍一集训Round#1

    到了之后看题,T1一看发现真熟悉,和之前做的一道题真的像,然后内心: 这里是绍一啊,不可能就出这么简单的题 我题意没理解错啊,这不是单独计算每条边的贡献么 维护一个人数的大小,然后直接搞一波就可以了吧 ...

随机推荐

  1. 教你阅读Python开源项目代码

    为什么要阅读开源代码 阅读 Python 开源项目代码主要有如下三个原因: 在工作过程中遇到一些问题 Google 和 StackOverFlow 等网站找不到解决办法,只能去翻源码. 对某些项目或者 ...

  2. 在linux中安装nginx

    linux系统安装在vmware中,首先在主机中利用shell工具与虚拟机连接 1.在linux中查看虚拟机的ip地址 在终端输入 ifconfig 红框里面就是ip地址 2.在主机中打开shell工 ...

  3. pytest参数化 parametrize

    pytest.mark.parametrize装饰器可以实现测试用例参数化 parametrizing 1.这里是一个实现检查一定的输入和期望输出测试功能的典型例子 # content of test ...

  4. java中堆栈的一些理解备忘

    堆:用来存放对象的信息,同一个类存放各自的成员变量,共享对象的方法. 栈:用来保存局部变量的值,包括基本数据类型的值.保存类的实例(堆区对象的引用).保存加载方法的帧. 常量池:包含了一个类型所有的对 ...

  5. c++ stl在竞赛里的使用总结

    SET bzoj2761: [JLOI2011]不重复数字 这题... count() 的用法,返回这个值出现的次数,但是在set里只会出现0次和1次,这个可以判断某个值是否在set里出现过 还有si ...

  6. Vue中封装axios

    参考: https://www.jianshu.com/p/7a9fbcbb1114 https://www.cnblogs.com/dreamcc/p/10752604.html 一.安装axios ...

  7. linux 安装 Django

    安装django的命令 pip install Django ## 这样运行默认安装的是最新版 备注 根据测试在python3.4基础上安装Django 1.8.9正式版是没有问题的,所以要执行下面命 ...

  8. Vs2013以管理员身份运行

    VS快捷方式目录下的devenv.exe 右键->兼容性疑难解答->疑难解答程序->勾选该程序需要附加权限即可,以后每次打开VS时都会以管理员身份运行了!

  9. 初步自学Java小结

    本周学习Java使我印象最深刻的Java开发环境的安装与设置,通过下载Eclipse IDE for Java Developers初步搭建好了Java开发环境,之后利用视频了解了Java程序的类型及 ...

  10. cmake编译升级

    cmake的升级依赖于gcc版本,例如cmake 3.15.3依赖与gcc 4.8以上的版本 1)先升级gcc到4.8 参考:https://blog.csdn.net/Kangshuo2471781 ...