【BZOJ3242】【NOI2013】快餐店(动态规划)

题面

BZOJ

题解

假设我们要做的是一棵树,那么答案显然是树的直径的一半。

证明?

假设树的直径是\(2d\),那么此时最远点的距离是\(d\)

假设存在一个点的距离大于\(d\),那么直径可以由这个点到达直径的一个端点拼出。

所以最远点距离为\(d\)。

现在的问题在基环树上。

可以用\(dp\)求出所有外向树上的直径以及能够一直向下延伸的最大深度\(f[i]\)。

显然最终在基环树上的答案一定只会经过基环树的一部分,

也就是如果从某条不在答案的路径上,把它断开,对于答案没有任何影响。

那么考虑枚举从哪个位置断开,然后维护一下最长链就好了。

我们把环上的点顺次放在一排,然后编号\(1..m\)

假设\(1->2->3->...->x\)的链长度为\(W[x]\)

那么最长链就是\(max(f[i]+f[j]+W[j]-W[i]),i\lt j\)

每次枚举断点,然后扫一遍求最大值,这样子的复杂度是\(O(n^2)\)的。

然后就是一堆奇奇怪怪的优化了,感觉我自己都说不清。

因为我是照着别人写的了 。。。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<algorithm>
  7. #include<set>
  8. #include<map>
  9. #include<vector>
  10. #include<queue>
  11. using namespace std;
  12. #define ll long long
  13. #define RG register
  14. #define MAX 111111
  15. inline int read()
  16. {
  17. RG int x=0,t=1;RG char ch=getchar();
  18. while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
  19. if(ch=='-')t=-1,ch=getchar();
  20. while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
  21. return x*t;
  22. }
  23. struct Line{int v,next,w;}e[MAX<<1];
  24. int h[MAX],cnt=1;
  25. inline void Add(int u,int v,int w){e[cnt]=(Line){v,h[u],w};h[u]=cnt++;}
  26. bool cir[MAX];
  27. int p[MAX<<1],top,dep[MAX],fa[MAX],n;
  28. ll f[MAX],ans,W[MAX<<1],Cir=1e18,pre1[MAX],pre2[MAX],l1[MAX],l2[MAX];
  29. int Q[MAX<<1],H,T;
  30. void findcir(int u,int ff)
  31. {
  32. dep[u]=dep[ff]+1;fa[u]=ff;
  33. for(int i=h[u];i;i=e[i].next)
  34. {
  35. int v=e[i].v;if(v==ff)continue;
  36. if(dep[v]&&dep[v]>dep[u])
  37. {
  38. for(int j=v;j!=u;j=fa[j])cir[j]=true,p[++top]=j;
  39. p[++top]=u;cir[u]=true;continue;
  40. }
  41. if(!dep[v])findcir(v,u);
  42. }
  43. }
  44. void dfs(int u,int ff)
  45. {
  46. for(int i=h[u];i;i=e[i].next)
  47. {
  48. int v=e[i].v;if(v==ff||cir[v])continue;
  49. dfs(v,u);ans=max(ans,f[u]+f[v]+e[i].w);
  50. f[u]=max(f[u],f[v]+e[i].w);
  51. }
  52. }
  53. int main()
  54. {
  55. n=read();
  56. for(int i=1;i<=n;++i)
  57. {
  58. int u=read(),v=read(),w=read();
  59. Add(u,v,w);Add(v,u,w);
  60. }
  61. findcir(1,0);
  62. for(int i=1;i<=top;++i)dfs(p[i],0);p[top+1]=p[1];
  63. for(int i=1;i<=top;++i)
  64. for(int j=h[p[i]];j;j=e[j].next)
  65. if(e[j].v==p[i+1]){W[i]=e[j].w;break;}p[top+1]=0;
  66. ll sum=0,mx=0;
  67. for(int i=1;i<=top;++i)
  68. {
  69. sum+=W[i-1];pre1[i]=max(pre1[i-1],f[p[i]]+sum);
  70. l1[i]=max(l1[i-1],f[p[i]]+mx+sum);
  71. mx=max(mx,f[p[i]]-sum);
  72. }
  73. ll tot=W[top];W[top]=sum=mx=0;
  74. for(int i=top;i;--i)
  75. {
  76. sum+=W[i];pre2[i]=max(pre2[i+1],f[p[i]]+sum);
  77. l2[i]=max(l2[i+1],f[p[i]]+mx+sum);
  78. mx=max(mx,f[p[i]]-sum);
  79. }
  80. Cir=l1[top];
  81. for(int i=1;i<top;++i)
  82. Cir=min(Cir,max(max(l1[i],l2[i+1]),pre1[i]+pre2[i+1]+tot));
  83. ans=max(ans,Cir);
  84. printf("%.1lf\n",ans/2.0);
  85. return 0;
  86. }

【BZOJ3242】【NOI2013】快餐店(动态规划)的更多相关文章

  1. bzoj3242 [Noi2013]快餐店

    Description 小T打算在城市C开设一家外送快餐店.送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小T希望快餐店的地址选在离最远的顾客距离最近的地方. 快餐店的顾客分布在城 ...

  2. BZOJ3242 [Noi2013]快餐店 【环套树 + 单调队列dp】

    题目链接 BZOJ3242 题解 题意很清楚,找一点使得最远点最近 如果是一棵树,就是直径中点 现在套上了一个环,我们把环单独拿出来 先求出环上每个点外向树直径更新答案,并同时求出环上每个点外向的最远 ...

  3. bzoj 3242: [Noi2013]快餐店 章鱼图

    3242: [Noi2013]快餐店 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 266  Solved: 140[Submit][Status] ...

  4. P1399 [NOI2013] 快餐店 方法记录

    原题题面P1399 [NOI2013] 快餐店 题目描述 小 T 打算在城市 C 开设一家外送快餐店.送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小 T 希望快餐店的地址选在离最 ...

  5. 动态规划:NOI2013 快餐店

    Description 小 T打算在城市C开设一家外送快餐店.送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小T希望快餐店的地址选在离最远的顾客距离最近 的地方. 快餐店的顾客分布 ...

  6. BZOJ3242/UOJ126 [Noi2013]快餐店

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  7. 3242: [Noi2013]快餐店 - BZOJ

    Description 小T打算在城市C开设一家外送快餐店.送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小T希望快餐店的地址选在离最远的顾客距离最近的地方. 快餐店的顾客分布在城 ...

  8. NOI2013 快餐店

    http://uoj.ac/problem/126 总的来说,还是很容易想的,就是有点恶心. 首先,很明显只有一个环. 我们先找出这个环,给各棵树编号id[i],然后各棵树分别以环上的点为根,求出每个 ...

  9. bzoj 3242: [Noi2013]快餐店

    Description 小T打算在城市C开设一家外送快餐店.送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小T希望快餐店的地址选在离最远的顾客距离最近的地方. 快餐店的顾客分布在城 ...

  10. CF835F Roads in the Kingdom/UOJ126 NOI2013 快餐店 树的直径

    传送门--CF 传送门--UOJ 题目要求基环树删掉环上的一条边得到的树的直径的最小值. 如果直接考虑删哪条边最优似乎不太可做,于是考虑另一种想法:枚举删掉的边并快速地求出当前的直径. 对于环上的点, ...

随机推荐

  1. 【Unity3d】ScriptableObject的简单用法

      ScriptableObject非常适合小数量的游戏数值. 使用ScriptableObject的时候需要注意,生成ScriptableObject数据文件需要自己写Editor代码实现. 大概的 ...

  2. javaweb(八)——HttpServletResponse对象(二)

    一.HttpServletResponse常见应用——生成验证码 1.1.生成随机图片用作验证码 生成图片主要用到了一个BufferedImage类, 生成随机图片范例: 1 package gacl ...

  3. windows下Mysql安装启动及常用操作

    1.下载mysql https://dev.mysql.com/downloads/ 2.配置环境变量 变量名:MYSQL_HOME 变量值:E:\MySql\mysql-8.0.15-winx64\ ...

  4. Smokeping配置

    参考文档: 官网:http://oss.oetiker.ch/smokeping/ 参考:http://jaminzhang.github.io/monitoring/smokeping-deploy ...

  5. Ztree结合jbox实现弹窗树结构

    点击添加分类,弹出事项选择框为jbox <a href="#" id="down{{row.id}}" style="display:none& ...

  6. 【Linux 运维】 date的使用

    date的使用 一.常用时间格式 #年.月.日 四位年大写,其余小写 [root@localhost ~]# date +%Y #长格式显示四位数年 [root@localhost ~]# date ...

  7. [leetcode-884-Uncommon Words from Two Sentences]

    We are given two sentences A and B.  (A sentence is a string of space separated words.  Each word co ...

  8. nginx原声方法按照每天日志切割保存

    首先配置日志变量,然后配置日志 在/etc/nginx/conf.d/default.conf 配置变量 server{ if ($time_iso8601 ~ "^(\d{4})-(\d{ ...

  9. Live Love(思维)

    DreamGrid is playing the music game Live Love. He has just finished a song consisting of n notes and ...

  10. php addslashes和stripslashes函数

    addslashes — 使用反斜线引用字符串 stripslashes — 反引用一个引用字符串   Example #1 一个 addslashes() 例子 <?php$str = &qu ...