题目描述

整个城市可以看做一个N个点,N条边的单圈图(保证图连通),唯一的环便是绕城的环路。保证环上任意两点有且只有2条路径互通。图中的其它部分皆隶属城市郊区。

现在,有一位名叫Jim的同学想在B市开店,但是任意一条边的2个点不能同时开店,每个点都有一定的人流量Pi,在该点开店的利润就等于该店的人流量Pi×K(K≤10000),K的值将给出。

Jim想尽量多的赚取利润,请问他应该在哪些地方开店?

输入格式

第一行一个整数N 代表城市中点的个数。城市中的N个点由0~N-1编号。

第二行N个正整数,表示每个点的人流量Pi(Pi≤10000)。

下面N行,每行2个整数A,B,表示A,B建有一条双向路。

最后一行一个实数K。

输出格式

一个实数M,(保留1位小数),代表开店的最大利润。


很明显是基环树的题。

首先最后的K是没有什么用的,因为我们的运算里只有加法,所以把K放到最后乘也不影响。我们先不把K算进去。

先考虑一棵树的情况。设dp(u,0/1)表示u的子树可以得到的最大利润,并且u是选(1)还是不选(0)。那么递推公式显然:

\[dp[u][1]=\sum_{v{\in}son[u]} dp[v][0];\\
dp[u][0]=\sum_{v{\in}son[u]} Max(dp[v][0],dp[v][1]);
\]

初始化dp(u,0)=0,dp(u,1)=P(u)。目标状态为Max(dp(root,0/1))。

然而基环树就不那么简单。

朴素的做法就是枚举环上的每条边,把它断掉之后原图会变成一棵树,然后在树上做刚才的dp,得出对应的ans。枚举完所有边后去最大值即可。

但是我们发现断开一条边以后对于每个点选与不选没有影响。但是可以消除后效性。所以我们只需要断开任意一条边,然后分别以这条边的两个端点为根dp一遍即可。

时间复杂度为O(N)。

#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 1000001
#define inf 0x3f3f3f3f
using namespace std; struct edge{
int to,next;
edge(){}
edge(const int &_to,const int &_next){ to=_to,next=_next; }
}e[maxn<<1];
int head[maxn],k;
int n,val[maxn],ans;
double K; inline int read(){
register int x(0),f(1); register char c(getchar());
while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }
while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
inline void add(const int &u,const int &v){ e[k]=edge(v,head[u]),head[u]=k++; } bool flag[maxn];
int s,t;
inline void getloop(){
for(register int i=0;i<k;i+=2){
int u=e[i].to,v=e[i^1].to;
if(flag[u]&&flag[v]){ s=u,t=v; return; }
flag[u]=flag[v]=true;
}
} int dp[maxn][2];
bool vis[maxn];
void dfs(int u){
vis[u]=true,dp[u][1]=val[u],dp[u][0]=0;
for(register int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(vis[v]) continue;
dfs(v),dp[u][0]+=max(dp[v][0],dp[v][1]),dp[u][1]+=dp[v][0];
}
} int main(){
memset(head,-1,sizeof head);
n=read();
for(register int i=1;i<=n;i++) val[i]=read();
for(register int i=1;i<=n;i++){
int u=read()+1,v=read()+1;
add(u,v),add(v,u);
}
scanf("%lf",&K); getloop();
dfs(s),ans=max(ans,dp[s][0]);
memset(vis,false,sizeof vis);
dfs(t),ans=max(ans,dp[t][0]);
printf("%.1lf\n",ans*K);
return 0;
}

luogu P1453 城市环路的更多相关文章

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

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

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

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

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

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

  4. P1453 城市环路

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

  5. 题解 P1453 【城市环路】

    P1453 城市环路 感觉基环树(or环套树)的题目一般都是找到树上的环,断掉一条边再进行树上的操作(如noip2018P5022 旅行) 双倍经验:P2607 [ZJOI2008]骑士 P1453和 ...

  6. luogu P1401 城市

    题目链接 luogu P1401 城市 题解 二分最小边权,dinic检验 代码 // luogu-judger-enable-o2 /* 二分最小边权,dinic检验 */ #include< ...

  7. luogu P4842 城市旅行

    嘟嘟嘟 好题,好题 刚开始突发奇想写了一个\(O(n ^ 2)\)暴力,结果竟然过了?!后来才知道是上传题的人把单个数据点开成了10s-- 不过不得不说我这暴力写的挺好看的.删边模仿链表删边,加边的时 ...

  8. Luogu P1401 城市(二分+网络流)

    P1401 城市 题意 题目描述 N(2<=n<=200)个城市,M(1<=m<=40000)条无向边,你要找T(1<=T<=200)条从城市1到城市N的路,使得最 ...

  9. [ZJOI2008]骑士 题解

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

随机推荐

  1. css 15-Sass入门

    15-Sass入门 #Sass简介 大家都知道,js 中可以自定义发量,css 仅仅是一个标记语言,不是编程语言,因此不可以自定义发量.不可以引用等等. 面对这些问题,我们现在来引入 Sass,简单的 ...

  2. B. Navigation System【CF 1320】

    传送门 题目:简单理解就是,我们需要开车从s点到t点.车上有一个导航,如果当前点为x,则导航会自动为你提供一条从x到t的最短的路线(如果有多条,则随机选一条),每走到下一个点则会实时更新最短路线,当然 ...

  3. P4735 最大异或和 01 Trie

    题目描述 给定一个非负整数序列 \(\{a\}\),初始长度为\(n\). 有 \(m\) 个操作,有以下两种操作类型: \(A\ x\):添加操作,表示在序列末尾添加一个数 \(x\),序列的长度 ...

  4. Python的一个mysql实例

    按公司名统计一定时期内入货的总车数,总重量还有总价格.数据表如下: 要用到的库是pymysql,读取excel表格的xlrd,写入excel的xlwt和复制excel模板的xlutils,代码如下: ...

  5. GeoServer安装部署流程

    1.双击geoserver-2.13.0.exe进行安装,点击Next进行下一步 2.GeoServer遵循GPL许可,点击I agree继续 3.选择要安装的程序文件目录,点击Next继续 4.点击 ...

  6. C#注册OCX控件

    注意 COM组件注册到注册表中的位置,是CLSID还是TypeLib 注册方法 代码执行 //声明注册方法 [DllImport("C:\\Windows\\barcodex.ocx&quo ...

  7. [.NET] - 初步认识AutoMapper

    初步认识AutoMapper AutoMapper 初步认识AutoMapper 前言 手动映射 使用AutoMapper 创建映射 Conventions 映射到一个已存在的实例对象   前言 通常 ...

  8. .net MVC 微信公众号 点击菜单拉取消息时的事件推送

    官方文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141016&token=&lang=zh_CN ...

  9. 在vue cli3.0 里面下载less,下载成功了还是提示没有 需要下载

    今天正好新建了一个项目,在用less的时候就各种花样报错提示我: Failed to resolve loader: less-loaderYou may need to install it.Err ...

  10. 线程 - AtomicInteger

    原理 AtomicInteger是如何使用非阻塞算法来实现并发控制的 性能提升 避免多线程的优先级倒置和死锁情况的发生 任然可能存在问题 ABA问题 CAS原理 调整具有竞争的并发应用程序的可伸缩性的 ...