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. 统一身份认证服务IdentityServer4实践

    导读 当企业的应用系统逐渐增多后,每个系统单独管理各自的用户数据容易形成信息孤岛,分散的用户管理模式阻碍了企业应用向平台化演进.当企业的业务发展到一定规模,构建统一的标准化账户管理体系将是必不可少的, ...

  2. 本地.local域名访问实现

    苹果的 Bonjour 的多址广播域名服务(mDNS) 使用".local "后缀来识别 Bonjour 可访问的设备 比如树莓派可以用用raspberrypi.local去访问非 ...

  3. 关闭visual studio code 智能提示功能

    对于程序初学者来说,应该少用IDE的提示功能,因为这样有助于记住一些常用的函数等功能.这也是为什么戏称喜欢用notepad++(windows)或者vim编辑器(Linux)来开发代码是大神的原因,而 ...

  4. ORACLE不常用但实用的技巧- 树查询 level用法

    树查询 使用树查询的前提条件是: 在一条记录中记录了当前节点的ID和这个节点的父ID. 注意:一旦数据中出现了循环记录,如两个节点互为对方的父结点,系统就会报 ORA-01436错误(ORA-0143 ...

  5. ubuntu set up 1 - 网络

    r2v has to be replaced.. 1. 官网下载zip版本,下载安装脚本 https://www.r2v.com/chapter_00/install.html https://ins ...

  6. LaTeX绘图

    http://math.uchicago.edu/~weinan/programs/tex_diagrams/diagrams.html 给大家分享下这个,用鼠标画diagrams,然后可以一键复制l ...

  7. flutter loading

    在发起请求时 需要有loading页面这样可以让用户知道当前正在操作,又可以防止多次点击等误操作,所以这里就自定义了一个loading页面 菊花使用flutter_spinkit里面的菊花来代替 在需 ...

  8. LINUX使用SSH远程终端时,如何将运行时间长的程序在后台挂起,下次SSH登陆时继续使用同一个SHELL?

    我在某个平台上购买了一个云服务器,LINUX操作系统无图形化界面,硬盘空间较小.虽然在平台上可以通过其自带网页版VNC界面登陆SHELL进而操控云主机,但是每次需要操控都得打开网页登陆进平台,然后再进 ...

  9. 控制台测试ajax

    有的时候需要测试下web项目中post.get请求是否正确,但是这个时候电脑上没有安装测试工具,怎么办呢?直接用浏览器控制台测试,打开网站,F12控制台,在控制台下复制粘贴下面的ajax请求,之后aj ...

  10. SD卡报错“error -110 whilst initialising SD card”

    目前开发遇到了某些SD卡和TI的SOC芯片的驱动不协调的地方,具体表现为: uboot 阶段初始化mmc dev 1 没有任何串口信息输出,无法读写mmc Kernel阶段报错”SD卡初始化失败 er ...