城市环路

Description

  一座城市,往往会被人们划分为几个区域,例如住宅区、商业区、工业区等等。B市就被分为了以下的两个区域——城市中心和城市郊区。在着这两个区域的中间是一条围绕B市的环路,环路之内便是B市中心。
  整个城市可以看做一个N个点,N条边的单圈图(保证图连通),唯一的环便是绕城的环路。保证环上任意两点有且只有2条路径互通。图中的其它部分皆隶属城市郊区。
  现在,有一位名叫Jim的同学想在B市开店,但是任意一条边的2个点不能同时开店,每个点都有一定的人流量Pi,在该点开店的利润就等于该店的人流量Pi×K(K≤10000),K的值将给出。
  Jim想尽量多的赚取利润,请问他应该在哪些地方开店?

Input

  第一行一个整数N 代表城市中点的个数。城市中的N个点由0~N-1编号。
  第二行N个正整数,表示每个点的人流量Pi(Pi≤10000)。
  下面N行,每行2个整数A,B,表示A,B建有一条双向路。
  最后一行一个实数K。

Output

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

Sample Input

4
1 2 1 5
0 1
0 2
1 2
1 3
2

Sample Output

12.0

Hint

【数据范围】
  对于20%的数据 N≤100.
  对于50%的数据 N≤2000.
  对于100%的数据 N≤100000.
 
↑以上是正经的题目描述XD
↓接下来是一点也不正经的题解啦
 
题目已经很明确了,这是个环,环上还有树。
就像这样:
 
乍一看会很麻烦对吧......那么我们先来考虑一下比较简单的情况。假如这一开始就只是个环呢?
那很简单啊,只要随便找个点开始,选择它跑一圈,不选它再跑一圈,取个最大值就行了嘛。
那么,加上树有什么影响呢?
没有。对,没有。只要提前把这个点引出去的树处理好就行了。
也就是说,只需要先对这棵子树进行一次动态规划,然后把这里能取到的最大值当做这个点的权值,这题就成了环形DP裸题啦23333。
 
主要流程:
①:Tarjan法先找出图中唯一的环。
②:枚举环上的每个点进行树形DP。
③:跑一遍环上DP。
 
听说这个东西好像叫环套树来着...去看了看其他几道环套树都好可怕啊QAQ
 
AC Code:

#include<cstring>
#include<cstdio>
#include<cmath>
#include<stack>
#include<iostream>
#include<algorithm>
using namespace std;
inline const int Read()
{
int Num=,Sgn=;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')Sgn=-;ch=getchar();}
while(isdigit(ch)){Num=(Num<<)+(Num<<)+ch-'';ch=getchar();}
return Num*Sgn;
} struct Edge
{
int Next,To;
}e[];
int h[]={},Cnt=;
void Addedge(int x,int y){e[++Cnt]=(Edge){h[x],y}; h[x]=Cnt;}
int a[]={};
double K;
int N; int Scnt=;
int DFN[]={},Lowlink[]={};
int Cir[]={},Belong[]={},Prt[]={};
int f[][]={},g[][]={}; stack<int>Sta; void Tarjan(int x)
{
Scnt++;
DFN[x]=Scnt; Lowlink[x]=Scnt;
Sta.push(x);
for(int i=h[x];i;i=e[i].Next)
{
int y=e[i].To;
if(!DFN[y])
{
Prt[y]=x;
Tarjan(y);
Lowlink[x]=min(Lowlink[x],Lowlink[y]);
}
else if(Prt[x]!=y)
Lowlink[x]=min(Lowlink[x],DFN[y]);
}
if(Lowlink[x]==DFN[x])
{
if(Sta.top()==x)
{
Sta.pop();
return;
}
int t;
do
{
t=Sta.top(); Sta.pop();
Cir[++Cir[]]=t;
Belong[t]=;
}while(t!=x);
}
} void DFS(int x)
{
f[x][]=; f[x][]=a[x];
for(int i=h[x];i;i=e[i].Next)
{
int y=e[i].To;
if(Prt[x]!=y&&!Belong[y])
{
Prt[y]=x;
DFS(y);
f[x][]+=max(f[y][],f[y][]);
f[x][]+=f[y][];
}
}
} int main()
{
N=Read();
for(int i=;i<=N;i++)
a[i]=Read();
for(int i=;i<=N;i++)
{
int Tx=Read(),Ty=Read();
Addedge(Tx+,Ty+); Addedge(Ty+,Tx+);
}
scanf("%lf",&K);
Tarjan();
int M=Cir[];
memset(Prt,,sizeof(Prt));
for(int i=;i<=M;i++)
DFS(Cir[i]);
for(int i=;i<=M;i++)
{
g[i][]=f[Cir[i]][];
g[i][]=f[Cir[i]][];
} f[][]=g[][]+g[][];
f[][]=g[][]+g[][];
for(int i=;i<=M;i++)
{
f[i][]=f[i-][]+g[i][];
f[i][]=max(f[i-][],f[i-][])+g[i][];
}
int Ans=;
Ans=max(f[M][],max(Ans,f[M][]));
f[][]=g[][]+g[][];
f[][]=-0x3f3f3f3f;
for(int i=;i<=M;i++)
{
f[i][]=max(f[i-][],f[i-][])+g[i][];
f[i][]=f[i-][]+g[i][];
}
Ans=max(Ans,f[M][]);
printf("%.1lf\n",(double)Ans*K);
return ;
}

一开始忘了环形要跑两遍...真是⑨一般的错误啊(笑)

BSOJ3760||洛谷P1453 城市环路 题解的更多相关文章

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

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

  2. 洛谷P2832 行路难 分析+题解代码【玄学最短路】

    洛谷P2832 行路难 分析+题解代码[玄学最短路] 题目背景: 小X来到了山区,领略山林之乐.在他乐以忘忧之时,他突然发现,开学迫在眉睫 题目描述: 山区有n座山.山之间有m条羊肠小道,每条连接两座 ...

  3. 【洛谷P3960】列队题解

    [洛谷P3960]列队题解 题目链接 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m ...

  4. 洛谷P2312 解方程题解

    洛谷P2312 解方程题解 题目描述 已知多项式方程: \[a_0+a_1x+a_2x^2+\cdots+a_nx^n=0\] 求这个方程在 \([1,m]\) 内的整数解(\(n\) 和 \(m\) ...

  5. 洛谷P1577 切绳子题解

    洛谷P1577 切绳子题解 题目描述 有N条绳子,它们的长度分别为Li.如果从它们中切割出K条长度相同的 绳子,这K条绳子每条最长能有多长?答案保留到小数点后2位(直接舍掉2为后的小数). 输入输出格 ...

  6. 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)

    洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...

  7. 洛谷 P1220 关路灯 题解

    Description 有 $n$ 盏路灯,每盏路灯有坐标(单位 $m$)和功率(单位 $J$).从第 $c$ 盏路灯开始,可以向左或向右关闭路灯.速度是 $1m/s$.求所有路灯的最少耗电.输入保证 ...

  8. 【洛谷P3410】拍照题解(最大权闭合子图总结)

    题目描述 小B有n个下属,现小B要带着一些下属让别人拍照. 有m个人,每个人都愿意付给小B一定钱让n个人中的一些人进行合影.如果这一些人没带齐那么就不能拍照,小B也不会得到钱. 注意:带下属不是白带的 ...

  9. [BZOJ 3039&洛谷P4147]玉蟾宫 题解(单调栈)

    [BZOJ 3039&洛谷P4147]玉蟾宫 Description 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地. ...

随机推荐

  1. 啊哈算法第四章第二节解救小哈Java实现

    package corejava; public class FourTwo { static int m;//(m,n)为几行几列 static int n; static int p;//(p,q ...

  2. C++重写new和delete,比想像中困难

    关于C++内存管理这话题,永远都不过时.在我刚出道的时候,就已经在考虑怎么检测内存泄漏(https://www.cnblogs.com/coding-my-life/p/3985164.html).想 ...

  3. leetcode数据库题目及答案汇总

    1. 第二高的薪水 select ifnull((select distinct Salary from Employee order by Salary desc limit 1,1),null) ...

  4. EasyUI在window中使用kindeditor 4.1.10在IE9中不能回显、获得焦点编辑的问题

    描述 :kindeditor4.1.10版本是当前最新的版本,在浏览器兼容性和功能方面都是值得一赞的,在开发中能方便快捷的满足一些开发需求. 问题 :  问题总是有的.  在使用过程中,遇到EasyU ...

  5. 【EFM32】EFM32芯片解锁、加锁操作

    [解锁] 使用J-Flash,新建Project,选择对应的EFM32芯片型号. 选择Target >> Connect >> Unsecure chip ,便进行解锁了,解锁 ...

  6. 利用linux curl爬取网站数据

    看到一个看球网站的以下截图红色框数据,想爬取下来,通常爬取网站数据一般都会从java或者python爬取,但本人这两个都不会,只会shell脚本,于是硬着头皮试一下用shell爬取,方法很笨重,但旨在 ...

  7. jmeter入门非GUI(三)

    配置见https://www.cnblogs.com/wish5714/p/9722193.html 该篇介绍非GUI模式的测试方法,及结果报告分析 简介 使用非 GUI 模式,即命令行模式运行 JM ...

  8. C代码通过编译器编译成可执行文件, 需经历 预处理、编译、汇编、链接 四个阶段

    内容借鉴 于yqzheng 一.预处理 1.任务: 进行宏定义展开.头文件展开.条件编译, 不检查语法 2.命令: gcc -E [源文件] -o [预处理文件] gcc -E hello.c -o ...

  9. 自己实现ArrayList

    思路: 一 载体 ArrayList是一个集合容器,必然要有一个保存数据的载体. public class MyArraylist { private final static int INIT_CO ...

  10. Git简单生成生成公钥和私钥方法

    Git简单生成生成公钥和私钥方法 Git配置 Git安装完之后,需做最后一步配置.打开git bash,分别执行以下两句命令 git config --global user.name “用户名” g ...