题解 P1453 【城市环路】
感觉基环树(or环套树)的题目一般都是找到树上的环,断掉一条边再进行树上的操作(如noip2018P5022 旅行)
双倍经验:P2607 [ZJOI2008]骑士
P1453和P2607这两题实际上就是基环树上的P1352 没有上司的舞会,用树形DP即可,但是因为有环,所以要先找到环再删一条边才能DP
至于树形DP就不多说了,毕竟是基环树,最主要的就是找环操作了,翻了翻题解,大概有下面几种方法:
一. 读入时判断
并查集 ,若两点在一个并查集中则记录下来,不连边不合并
(不建议使用)bool记录点是否出现过,若读入时两点在之前都已出现了,则为环,不连边(BUG:本题数据较弱可过,但可能在一些数据中出错,看评论中有一组hack数据:5 1 2 3 4 5 0 1 2 3 2 4 0 2 3 4 9.0,答案为63.0,但这种找环方法会超时)
二、读入后判断
如本程序,dfs找环,找到时记录两点a,b或边编号e,dp时不仅要判断v!=fa,还应判断(u!=a || v!=b) && (u!=b || v!=a)或(e!=i && (e^1)!=i)(双向边)
(不建议使用)连单向边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 【城市环路】的更多相关文章
- BSOJ3760||洛谷P1453 城市环路 题解
城市环路 Description 一座城市,往往会被人们划分为几个区域,例如住宅区.商业区.工业区等等.B市就被分为了以下的两个区域——城市中心和城市郊区.在着这两个区域的中间是一条围绕B市的环路,环 ...
- 洛谷 P1453 城市环路 ( 基环树树形dp )
题目链接 题目背景 一座城市,往往会被人们划分为几个区域,例如住宅区.商业区.工业区等等.B市就被分为了以下的两个区域--城市中心和城市郊区.在着这两个区域的中间是一条围绕B市的环路,环路之内便是B市 ...
- P1453 城市环路
题目背景 一座城市,往往会被人们划分为几个区域,例如住宅区.商业区.工业区等等.B市就被分为了以下的两个区域——城市中心和城市郊区.在着这两个区域的中间是一条围绕B市的环路,环路之内便是B市中心. 题 ...
- luogu P1453 城市环路
题目描述 整个城市可以看做一个N个点,N条边的单圈图(保证图连通),唯一的环便是绕城的环路.保证环上任意两点有且只有2条路径互通.图中的其它部分皆隶属城市郊区. 现在,有一位名叫Jim的同学想在B市开 ...
- LUOGU P1453 城市环路(基环树+dp)
传送门 解题思路 一道基环树上$dp$的题,这种题比较套路吧,首先第一遍$dfs$把环找出来,然后对于环上的每一个点都向它子树内做一次树形$dp$,$f[i][0/1]$表示到了$i$这个点选或不选的 ...
- [ZJOI2008]骑士 题解
题面 这道题稍微想一想就会联想到树形DP的入门题:没有上司的舞会: 但是再想一想会发现这根本就不是一颗树,因为它比树多了一条边: 这时候我们引入一个新的概念:基环树: 顾名思义(??),基环树就是在一 ...
- 2021record
2021-10-14 P2577 [ZJOI2004]午餐 2021-10-13 CF815C Karen and Supermarket(小小紫题,可笑可笑) P6748 『MdOI R3』Fall ...
- 2018 AI产业界大盘点
2018 AI产业界大盘点 大事件盘点 “ 1.24——Facebook人工智能部门负责人Yann LeCun宣布卸任 Facebook人工智能研究部门(FAIR)的负责人Yann LeCun宣布卸 ...
- 绍一集训Round#1
到了之后看题,T1一看发现真熟悉,和之前做的一道题真的像,然后内心: 这里是绍一啊,不可能就出这么简单的题 我题意没理解错啊,这不是单独计算每条边的贡献么 维护一个人数的大小,然后直接搞一波就可以了吧 ...
随机推荐
- 实现Windows数据更新
一.枚举 枚举是一组描述性的名称 定义一组有限的值,不能包含方法 对可能的值进行约束 .定义枚举类 public enum Gender { Male,Female } .使用枚举表示整数值 publ ...
- 使用ADO.NET 访问数据库
一.ADO.NET :用于连接数据库的技术 1.ADO.NET分为两大组件 DataSet:数据集 .NET FRAMWORK :用于连接到数据库,发送命令,检索结果 2.ADO.NET四大核心对象 ...
- unity踩坑2020-01-21
这几天一直在测试一个类似于传奇的2d界面游戏,目前做的测试为: 人物动作响应,主要是8方向的判断和资源文件精灵的刷新. 学到的知识点: 1,Enum.GetHashCode() 可以得到这个枚举的索引 ...
- P5168 xtq玩魔塔 [克鲁斯卡尔重构树+带修莫队]
P5168 xtq玩魔塔 又是码农题- 利用克鲁斯卡尔重构树的性质 我们就可以得出 \(dep\) 值小的,肯定比 \(dep\) 大的值要优. 于是第二问就可以直接 LCA 求出来了- 至于第三问, ...
- liunx 查找locate
使用 安装 yum install mlocate 更新数据库 updatedb 查找my.cnf文件 locate my.cnf
- ABC155 D pair 边界处理取整
ABC155 D pair 取整坑点 思路 很常见的一道题,二分找答案,然后看这个答案排rank?,排rank?用二分继续找一遍二分套二分即可,就是边界比较烦,老年人写的心情烦躁 老年人被取整坑的几天 ...
- Pytest学习10-pytest与unittest的区别
一.用例编写规则 1.unittest提供了test cases.test suites.test fixtures.test runner相关的类,让测试更加明确.方便.可控.使用unittest编 ...
- mac 命令行下 vim 的使用
vi/vim 使用实例 使用 vi 来建立名为 test.txt 的文件 vi test.txt1按下 ESC 按钮回到一般模式 在一般模式中按下 :wq 储存后离开 vi 基本上 vi/vim 共分 ...
- 重载(Overload)和重写(Override)的区别是什么?
首先java程序的运行分为编译和运行两部分. 所以重载和重写在这一点就有很明显的区别,因为重写方法的方法名和参数个数类型都一样,所以在java虚拟机的编译阶段是识别不出重写的方法的不同,在运行期间才可 ...
- C++-有感
今日在图书馆待了差不多一天,我都忘了我吃饭了没,拿着看视频学习,没啦,主要还是看书,突然感觉有点写不动了. 明天开始不带电脑了,准备把数据结构书重新过一遍,算了,还是不用C++写了,感觉C++居然做题 ...