城市环路

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. 嵌入式linux——说明(零)

    之前就学习过嵌入式linux,但是那时候并没有完全投入,学习的也不科学系统,没有笔记,也没有自己写很多的代码来练习,所以到现在是基本归零了,现在比较有富裕的时间来系统的学习,从今天开始要克服每一个学习 ...

  2. 在Python脚本中调用Django环境

    import os if __name__ == '__main__': os.environ.setdefault("DJANGO_SETTINGS_MODULE", " ...

  3. R语言输出高质量图片

    Rstudio画图之后保存的 图片格式如下 上面的几种格式可以直接插入word文档中,但是图片质量很低,锯齿感很明显.若生成PDF,为矢量图(不懂),但是不可以插入word文档中. 最简便的方法就是对 ...

  4. JSFL元件类型判断 转载于 https://blog.csdn.net/linking530/article/details/8364600

    //获取舞台上第一层第一帧上的全部元件 var els = fl.getDocumentDOM().getTimeline().layers[0].frames[0].elements; //遍历元件 ...

  5. ORM项目中小知识点积累

    申明:一下内容均建立在零基础小白的角度上,大佬们求放过~ 1.如何通过类建立外键关联 2.模板语言固定搭配 3.浏览器报错处理 4.后台取值方式 5.外键管理修改相关操作 6.两种(给后台偷偷传递消息 ...

  6. Fiddler基础使用三之请求过滤

    在我们抓包的时候如果不设置过滤,那么所有操作中的请求都会被捕获下来,如果我们只想查看指定或者某些请求信息,那么太多的session会给我们造成困扰,增加查找难度.所以我们需要设置过滤区域.fiddle ...

  7. 《DOM Scripting》学习笔记-——第七章 动态创建html内容

    本章内容: 1.动态创建html内容的“老”技巧:document.write()和innerHTML属性 2.DOM方法:createElement(),creatTextNode(),append ...

  8. java中的数据导出到Excel表中

    整个项目中导出数据到.Excel的源码 import java.io.BufferedOutputStream; import java.io.FileInputStream; import java ...

  9. webpack 4.0配置2

    上个博客记录了webpack 的基本配置今天主要是css-loader的介绍,包括单独提出css,压缩css.js文件 这里使用的插件npm 地址:https://www.npmjs.com/pack ...

  10. JQuery+formValidator实现表单验证

    <!-- 需求: 用户注册页面要有用户名.密码.确认密码.邮箱 用户名文本框:用户名不能为空,且必须为数字与字母的6到12位的组合 密码框:密码不能为空,最少6位,包括至少1个大写字母,1个小写 ...