正解:贪心+倍增+二分答案

解题报告:

正好想做noip的题目然后又想落实学长之前讲的题?于是就找上了这题

其实之前做过,70,然后实在细节太多太复杂就不了了之,现在再看一遍感觉又一脸懵了...

从标签就可以发现是个很麻烦考虑的点很多的问题,所以分开按步骤梳理我觉得应该会好些qwq

帕1,贪心

首先最最基本的思想要想到趴?就是贪心,就是,如果我不能跑到首都,我肯定是尽量往上跑;然后如果能跑到首都就先跑到首都再想怎么分配

帕2,倍增

已经发现是要往上提了,自然考虑倍增,于是写个函数预处理掉倍增这事儿

  1. void dfs1(int u,int fafa)
  2. {
  3. for(int i=head[u];i;i=edge[i].next)
  4. ]=u;d[edge[i].to][]=edge[i].wei;dis[edge[i].to]=dis[u]+edge[i].wei;dfs1(edge[i].to,u);}
  5. }
  6. inline void pre()
  7. {
  8. dfs1(,);
  9. rp(i,,)
  10. rp(j,,n)fa[j][i]=fa[fa[j][i-]][i-],d[j][i]=d[j][i-]+d[fa[j][i-]][i-];
  11. }
  12. //分了俩段,结构更好看qwq

这是代码

帕3,二分

可以发现这个显然是个能二分的自然是想到二分

于是就写个check函数

然后这题就结束了

不存在的这题最麻烦的地方就在这个check函数趴?

然后接下来几个帕都是港这个check函数

关于check函数:

帕1,上提

通过之前预处理出的倍增往上走就是了

  1. inline int stp(int u,int lim)
  2. {my(i,,)if(fa[u][i] && d[u][i]<=lim)lim-=d[u];[i],u=fa[u][i];return u;}
  3. //lim:二分的那个时间

这还是代码

帕2,判断是否到首都

如果没到首都就让它呆哪儿,到了首都登记下它还能走多久

  1. rp(i,,m)
  2. {
  3. int upup=stp(arm[i],limit);
  4. )vis[upup]=;
  5. else army[++cnt].sid=ff[i],army[cnt].tim=limit-dis[arm[i]];
  6. }
  7. //判断:如果不能到就停哪儿,能到就登记下(就像之前贪心所说

这又是代码

帕3,处理首都的亲崽有几个还没驻扎

再写个函数,判断有几个崽没被驻扎,登记下来(如果都被驻扎了就可以直接GG了退出掉

(对了我登记那儿忘复制来了但是又懒得编辑了就这样,自己去整个程序里看就是了,就在dfs后面qwq

  1. void dfs2(int u)
  2. {
  3. ,orzgoldgenius=;
  4. for(int i=head[u];i;i=edge[i].next)
  5. {
  6. ])
  7. {
  8. orzgoldgenius=;
  9. dfs2(edge[i].to);
  10. ;
  11. }
  12. }
  13. vis[u]=orzcjk&orzgoldgenius;
  14. }
  15. dfs2();

这双是代码

帕4,分配

把登记了的到了首都的发配给没有被驻扎的崽子们那儿去(关于这里的处理似乎有争议啊...等下港qwq   争议被抹掉了没有争议

不过关于分配细节挺多的要注意下嗷

  1. sort(army+,army+cnt+);sort(ned+,ned+cjk+,cmp);
  2. rp(i,,cjk)
  3. {
  4. if(!vis[ned[i]])
  5. {
  6. )return false;
  7. )
  8. {
  9. if(army[now].tim<dis[ned[i]] && now!=cnt)
  10. {
  11. vis[army[now].sid]=true;
  12. if(ned[i]==army[now].sid)break;
  13. ++now;
  14. }
  15. else
  16. {
  17. if(now==cnt)break;
  18. if(army[now].sid!=ned[i] && (!vis[army[now].sid]))
  19. {
  20. vis[army[now].sid]=true;
  21. ++now;
  22. }
  23. else break;
  24. }
  25. }
  26. if(now==cnt)if(army[now].tim<dis[ned[i]] && army[now].sid!=ned[i])return false;
  27. vis[ned[i]]=true;++now;
  28. }
  29. }
  30. return true;

这叒是代码

然后就真滴讲完辽,二分什么的太套路了懒得放

最后放程序

overrrr

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define rp(i,x,y) for(register int i=x;i<=y;++i)
  4. #define my(i,x,y) for(register int i=x;i>=y;--i)
  5. #define mp make_pair
  6. #define pi pair<int,int>
  7.  
  8. ,M=;
  9. ,fa[N][],d[N][],dis[N],ned[N],ff[N];
  10. struct ed{int to,next,wei;}edge[M];
  11. struct alive{int sid,tim;}army[N];
  12. bool vis[N];
  13. bool operator <(alive x,alive y){return x.tim<y.tim;}
  14.  
  15. inline int read()
  16. {
  17. ;;
  18. '))ch=getchar();
  19. ;
  20. )+(x<<)+(ch^'),ch=getchar();
  21. return y?x:-x;
  22. }
  23. inline void add(int x,int y,int z){edge[++tot].to=y;edge[tot].next=head[x];edge[tot].wei=z;head[x]=tot;}
  24. void dfs1(int u,int fafa)
  25. {
  26. for(int i=head[u];i;i=edge[i].next)
  27. ]=u;d[edge[i].to][]=edge[i].wei;dis[edge[i].to]=dis[u]+edge[i].wei;dfs1(edge[i].to,u);}
  28. }
  29. void dfs2(int u)
  30. {
  31. ,orzgoldgenius=;
  32. for(int i=head[u];i;i=edge[i].next)
  33. {
  34. ])
  35. {
  36. orzgoldgenius=;
  37. dfs2(edge[i].to);
  38. ;
  39. }
  40. }
  41. vis[u]=orzcjk&orzgoldgenius;
  42. }
  43. inline void pre()
  44. {
  45. dfs1(,);
  46. rp(i,,)
  47. rp(j,,n)fa[j][i]=fa[fa[j][i-]][i-],d[j][i]=d[j][i-]+d[fa[j][i-]][i-];
  48. }
  49. inline ,)if(fa[u][i] && d[u][i]<=lim)lim-=d[u][i],u=fa[u][i];return u;}
  50. inline bool cmp(int x,int y){return dis[x]<dis[y];}
  51. bool jud(int limit)
  52. {
  53. ;memset(vis,,sizeof(vis));
  54. rp(i,,m)
  55. {
  56. int upup=stp(arm[i],limit);
  57. )vis[upup]=;
  58. else army[++cnt].sid=ff[i],army[cnt].tim=limit-dis[arm[i]];
  59. }
  60. dfs2();
  61. ,now=;
  62. ];i;i=edge[i].next)if(!vis[edge[i].to])ned[++cjk]=edge[i].to;
  63. sort(army+,army+cnt+);sort(ned+,ned+cjk+,cmp);
  64. rp(i,,cjk)
  65. {
  66. if(!vis[ned[i]])
  67. {
  68. )return false;
  69. )
  70. {
  71. if(army[now].tim<dis[ned[i]] && now!=cnt)
  72. {
  73. vis[army[now].sid]=true;
  74. if(ned[i]==army[now].sid)break;
  75. ++now;
  76. }
  77. else
  78. {
  79. if(now==cnt)break;
  80. if(army[now].sid!=ned[i] && (!vis[army[now].sid]))
  81. {
  82. vis[army[now].sid]=true;
  83. ++now;
  84. }
  85. else break;
  86. }
  87. }
  88. if(now==cnt)if(army[now].tim<dis[ned[i]] && army[now].sid!=ned[i])return false;
  89. vis[ned[i]]=true;++now;
  90. }
  91. }
  92. return true;
  93. }
  94. inline ,))x=fa[x][i];return x;}
  95.  
  96. int main()
  97. {
  98. n=read();rp(i,,n-){int t1=read(),t2=read(),t3=read();add(t1,t2,t3);add(t2,t1,t3);}
  99. pre();
  100. m=read();rp(i,,m)arm[i]=read(),ff[i]=getf(arm[i]);
  101. while(l<=r)
  102. {
  103. ;
  104. ;
  105. ;
  106. }
  107. !=l)printf("%d\n",l);
  108. else printf("-1\n");
  109. ;
  110. }

这,依然是代码(...我是不是有点无聊啊233333333

啊森气!我重载运算符的时候把'<'重载成'>'了,然后调了一晚上...最近效率太太太低了我都想扇自己耳巴子了...

upd:18/11/03

  总算A了?但是有个事儿我真的没懂...这样的,就是我想剪一波枝?然后我就想着鸭,如果我一个城市读入了很多次其实我是不用重复算的对趴,然后如果一个城市的爹的祖宗已经读入了我也不用重复算了它的爹了直接返回ff[i]就成了对趴?

      哇我觉得这个思路真实好到爆炸了?然后我就成功90了?然后我删了那个剪枝就A了?

      什么鬼啊你家祖宗还带变的嘛???什么玩意儿啊...实力哭爆了...我我我我调了半小时就因为这玩意儿?

      哦我还发现我最近经常调试调很久,,,代码半小时debug三天就是我了:(

再放个辛酸的提交记录  不放了,蓝瘦

所以到底为什么会这样啊???我觉得我这波剪枝不可能错啊???什么鬼嘛QAQ

洛谷P1084 疫情控制 [noip2012] 贪心+树论+二分答案 (还有个小bugQAQ的更多相关文章

  1. 洛谷P1084 疫情控制(贪心+倍增)

    这个题以前写过一遍,现在再来写,感觉以前感觉特别不好写的细节现在好些多了,还是有进步吧. 这个题的核心思想就是贪心+二分.因为要求最小时间,直接来求问题将会变得十分麻烦,但是如果转换为二分答案来判断可 ...

  2. 洛谷P1084 疫情控制(NOIP2012)(二分答案,贪心,树形DP)

    洛谷题目传送门 费了几个小时杠掉此题,如果不是那水水的数据的话,跟列队的难度真的是有得一比... 话说蒟蒻仔细翻了所有的题解,发现巨佬写的都是倍增,复杂度是\(O(n\log n\log nw)\)的 ...

  3. [NOIP2012] 提高组 洛谷P1084 疫情控制

    题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都, 也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散 ...

  4. NOIP2012 洛谷P1084 疫情控制

    Description: H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控制疫情 ...

  5. 洛谷 P1084 疫情控制 —— 二分+码力

    题目:https://www.luogu.org/problemnew/show/P1084 5个月前曾经写过一次,某个上学日的深夜,精疲力竭后只有区区10分,从此没管... #include< ...

  6. 洛谷P1084 疫情控制

    题目 细节比较多的二分+跟LCA倍增差不多的思想 首先有这样一个贪心思路,深度越低的检查点越好,而最长时间和深度具有单调性,即给定时间越长,每个军队能向更浅的地方放置检查点.因此可以考虑二分时间,然后 ...

  7. 2018.09.26洛谷P1084 疫情控制(二分+倍增)

    传送门 好题啊. 题目要求的最大值最小,看到这里自然想到要二分答案. 关键在于怎么检验. 显然对于每个点向根走比向叶节点更优. 因此我们二分答案之后,用倍增将每个点都向上跳到跳不动为止. 这时我们ch ...

  8. D 洛谷 P3602 Koishi Loves Segments [贪心 树状数组+堆]

    题目描述 Koishi喜欢线段. 她的条线段都能表示成数轴上的某个闭区间.Koishi喜欢在把所有线段都放在数轴上,然后数出某些点被多少线段覆盖了. Flandre看她和线段玩得很起开心,就抛给她一个 ...

  9. 洛谷P2839 [国家集训队]middle 主席树_二分

    Code: #include <cstdio> #include <algorithm> #include <cstring> #include <strin ...

随机推荐

  1. Kafka版本升级 ( 0.10.0 -> 0.10.2 )

    升级Kafka集群的版本其实很简单,核心步骤只需要4步,但是我们需要在升级的过程中确保每一步操作都不会“打扰”到producer和consumer的正常运转.为此,笔者在本机搭了一个测试环境进行实际的 ...

  2. URI跳转方式地图导航的代码实践

    本文转载至 http://adad184.com/2015/08/11/practice-in-mapview-navigation-with-URI/ 前言 之前介绍了我正在做的是一款定位主打的应用 ...

  3. codeforces水题100道 第十题 Codeforces Round #277 (Div. 2) A. Calculating Function (math)

    题目链接:www.codeforces.com/problemset/problem/486/A题意:求表达式f(n)的值.(f(n)的表述见题目)C++代码: #include <iostre ...

  4. Python正则表达式 学习笔记

    python第一个正则表达式 1. import re : python正则表达式模块 2. 第一个正则表达式 re.compile(r'imooc') pattern.match('imooc py ...

  5. c++学习笔记—单链表基本操作的实现

    用c++语言实现的单链表基本操作,包括单链表的创建(包括头插法和尾插法建表).结点的查找.删除.排序.打印输出.逆置.链表销毁等基本操作. IDE:vs2013 具体实现代码如下: #include  ...

  6. JS使用中碰到的一些问题

    settimeout: 1.setTimeout(function () {//这个则会在1秒后进行弹出1 alert(1); }, 1000); 2.setTimeout(alert(1), 100 ...

  7. Linux IPC BSD Pipe

    mkfifo() //创建有名管道(FIFO special file),创建完了就像普通文件一样open(),再读写,成功返回0,失败返回-1设errno.VS$man 3 mkfifo #incl ...

  8. MFC 三种消息

    在MFC应用程序中传输的消息有三种类型:窗口消息.命令消息和控件通知. (1)窗口消息:WM_XXX 窗口消息(Window Message)一般与窗口的内部运作有关,如:创建窗口.绘制窗口和销毁窗口 ...

  9. 告知你不为人知的UDP-连接性和负载均衡

    版权声明:本文由黄日成原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/812444001486438028 来源:腾云阁 h ...

  10. 原生js--异步请求

    1.异步请求的方法: iframe.script.XMLHttpRequest.comet(服务器端发起) 2.XMLHttpRequest request = new XMLHttpRequest( ...