题目描述

H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,

也是树中的根节点。

H 国的首都爆发了一种危害性极高的传染病。当局为了控制疫情,不让疫情扩散到边境

城市(叶子节点所表示的城市),决定动用军队在一些城市建立检查点,使得从首都到边境

城市的每一条路径上都至少有一个检查点,边境城市也可以建立检查点。但特别要注意的是,

首都是不能建立检查点的。

现在,在 H 国的一些城市中已经驻扎有军队,且一个城市可以驻扎多个军队。一支军队可以在有道路连接的城市间移动,并在除首都以外的任意一个城市建立检查点,且只能在

一个城市建立检查点。一支军队经过一条道路从一个城市移动到另一个城市所需要的时间等

于道路的长度(单位:小时)。

请问最少需要多少个小时才能控制疫情。注意:不同的军队可以同时移动。

输入输出格式

输入格式:

第一行一个整数 n,表示城市个数。

接下来的 n-1 行,每行 3 个整数,u、v、w,每两个整数之间用一个空格隔开,表示从

城市 u 到城市 v 有一条长为 w 的道路。数据保证输入的是一棵树,且根节点编号为 1。

接下来一行一个整数 m,表示军队个数。

接下来一行 m 个整数,每两个整数之间用一个空格隔开,分别表示这 m 个军队所驻扎

的城市的编号。

输出格式:

共一行,包含一个整数,表示控制疫情所需要的最少时间。如果无法控制疫情则输出-1。

输入输出样例

输入样例#1:

  1. 4
  2. 1 2 1
  3. 1 3 2
  4. 3 4 3
  5. 2
  6. 2 2
输出样例#1:

  1. 3

说明

【输入输出样例说明】

第一支军队在 2 号点设立检查点,第二支军队从 2 号点移动到 3 号点设立检查点,所需

时间为 3 个小时。

【数据范围】

保证军队不会驻扎在首都。

对于 20%的数据,2≤ n≤ 10;

对于 40%的数据,2 ≤n≤50,0<w <10^5;

对于 60%的数据,2 ≤ n≤1000,0<w <10^6;

对于 80%的数据,2 ≤ n≤10,000;

对于 100%的数据,2≤m≤n≤50,000,0<w <10^9。

NOIP 2012 提高组 第二天 第三题

又理解错题了,是同时的。

往往不容易直接进行最优解的时候都要考虑一下二分。那么就给你一个限定时间,你在限定时间之内完成就好了。

我们会发现,其实你越往上走,覆盖的路径越多,所以每个点都尽量往上走。

有些点走到了根,有些点没有,没有走到根的点就直接对子树做贡献。走到根的点要合理分配,使得在限定时间内覆盖子树。

这时如果子树没有被覆盖,那么从根往下走一步就好了。

很容易想到贪心,两个都排序,大的对大的,小的对小的。

但是有一个问题,有时候你从子树走到根,然后走不回来了。【但其实他留在那棵子树上可能更好【相当于他下来完全不用时间的

考虑一个子树,从他出发的点剩余时间最少的是x,如果x不能走回来,那么就让x留在那子树上,否则这种情况不用管【因为都能走回来了,就不用管了

为什么走不会来,就直接留下呢,因为这样你覆盖这棵子树一定用了其他点,说明这个点比x更强,那么如果x能做到的事,这个点更能做到,所以x不需做别的,管好这棵子树就好。

【倍增打错了,捂脸

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. #include<queue>
  7. #include<cmath>
  8. using namespace std;
  9. #define Maxn 50010
  10. #define Maxd 25
  11. #define INF 0xfffffff
  12. #define LL long long
  13.  
  14. struct node
  15. {
  16. LL x,y,next,c;
  17. }t[Maxn*];LL len;
  18. LL first[Maxn];
  19. LL n,m;
  20.  
  21. void ins(LL x,LL y,LL c)
  22. {
  23. t[++len].x=x;t[len].y=y;t[len].c=c;
  24. t[len].next=first[x];first[x]=len;
  25. }
  26.  
  27. LL mymin(LL x,LL y) {return x<y?x:y;}
  28.  
  29. bool am[Maxn];
  30. LL ff[Maxn],d[Maxn][Maxd],f[Maxn][Maxd],id[Maxn];
  31. LL dis[Maxn],dep[Maxn];
  32.  
  33. void dfs(LL x,LL fa)
  34. {
  35. for(LL i=;i<=;i++)
  36. d[x][i]=d[f[x][i-]][i-],f[x][i]=f[f[x][i-]][i-];
  37. if(fa==) ff[x]=x;
  38. else ff[x]=ff[fa];
  39. for(LL i=first[x];i;i=t[i].next) if(t[i].y!=fa)
  40. {
  41. LL y=t[i].y;
  42. d[y][]=t[i].c;f[y][]=x;
  43. dis[y]=dis[x]+t[i].c;dep[y]=dep[x]+;
  44. dfs(y,x);
  45. }
  46. }
  47.  
  48. LL mn[Maxn];
  49. bool g[Maxn];
  50. void dfs2(LL x,LL fa)
  51. {
  52. LL ans=;
  53. bool ok=,sm=;
  54. for(LL i=first[x];i;i=t[i].next) if(t[i].y!=fa)
  55. {
  56. sm=;
  57. LL y=t[i].y;
  58. dfs2(y,x);
  59. if(!g[y]) ok=;
  60. }
  61. if(am[x]||(ok&&sm)) g[x]=;
  62. }
  63.  
  64. struct hp
  65. {
  66. LL x,w;
  67. }q1[Maxn],q2[Maxn];
  68.  
  69. LL lf[Maxn];
  70.  
  71. bool cmp(hp x,hp y) {return x.w<y.w;}
  72.  
  73. bool us[Maxn];
  74. bool check(LL x)
  75. {
  76. memset(am,,sizeof(am));
  77. memset(g,,sizeof(g));
  78. memset(lf,-,sizeof(lf));
  79. for(LL i=first[];i;i=t[i].next) mn[t[i].y]=-;
  80. LL xx;
  81. for(LL i=;i<=m;i++)
  82. {
  83. LL now=id[i];xx=x;
  84. for(LL j=;j>=;j--)
  85. {
  86. if((<<j)<=dep[now]&&dis[now]-dis[f[now][j]]<=xx)
  87. {
  88. xx-=dis[now]-dis[f[now][j]];
  89. now=f[now][j];
  90. }
  91. }
  92. am[now]=;
  93. if(now==) lf[i]=x-dis[id[i]];
  94. if(now==&&(mn[ff[id[i]]]==-||lf[mn[ff[id[i]]]]>lf[i])) mn[ff[id[i]]]=i;
  95. }
  96. dfs2(,);
  97. LL l1=,l2=;
  98. for(LL i=;i<=m;i++) if(lf[i]!=-) q1[++l1].x=i,q1[l1].w=lf[i];
  99. // for(LL i=1;i<=m;i++) if(id[i]==1) q1[++l1].x=0,q1[l1].w=x;
  100. for(LL i=first[];i;i=t[i].next)
  101. {
  102. LL y=t[i].y;
  103. if(!g[y]) q2[++l2].x=y,q2[l2].w=t[i].c;
  104. }
  105. memset(g,,sizeof(g));
  106. sort(q1+,q1++l1,cmp);
  107. sort(q2+,q2++l2,cmp);
  108. LL j=,i;
  109. // LL k=l1;
  110. if(l1<l2) return ;
  111. for(i=;i<=l2;i++)if(mn[q2[i].x]!=-&&g[mn[q2[i].x]]==&&lf[mn[q2[i].x]]<q2[i].w)
  112. {
  113. g[mn[q2[i].x]]=;
  114. q2[i].x=-;
  115. }
  116.  
  117. for(i=;i<=l2;i++) if(q2[i].x!=-)
  118. {
  119. while(g[q1[j].x]&&j<=l1) j++;
  120. // if(j>l1) return 0;
  121. /*if(mn[q2[i].x]!=-1&&g[mn[q2[i].x]]==0&&lf[mn[q2[i].x]]<q2[i].w)
  122. {
  123. g[mn[q2[i].x]]=1;
  124. continue;
  125. }*/
  126. /*else*/ if(mn[q2[i].x]==-||lf[mn[q2[i].x]]>=q2[i].w)
  127. {
  128. while((g[q1[j].x]||q1[j].w<q2[i].w)&&j<=l1) j++;
  129. }
  130. if(j>l1) return ;
  131. g[q1[j].x]=;
  132. j++;
  133. }
  134. return ;
  135. }
  136.  
  137. void ffind(LL l,LL r)
  138. {
  139. LL ans=-;
  140. while(l<r)
  141. {
  142. LL mid=(l+r)>>;
  143. if(check(mid)) ans=mid,r=mid;
  144. else l=mid+;
  145. }
  146. if(check(l)) ans=l;
  147. printf("%lld\n",ans);
  148. }
  149.  
  150. int main()
  151. {
  152. scanf("%lld",&n);
  153. len=;
  154. memset(first,,sizeof(first));
  155. LL sum=;
  156. for(LL i=;i<n;i++)
  157. {
  158. LL x,y,c;
  159. scanf("%lld%lld%lld",&x,&y,&c);
  160. ins(x,y,c);ins(y,x,c);
  161. sum+=c;
  162. }
  163. memset(am,,sizeof(am));
  164. scanf("%lld",&m);
  165. for(LL i=;i<=m;i++)
  166. {
  167. LL x;
  168. scanf("%lld",&x);
  169. am[x]++;
  170. id[i]=x;
  171. }
  172. f[][]=;
  173. dis[]=;dep[]=;
  174. dfs(,);
  175. ffind(,sum);
  176. return ;
  177. }

【打得丑并且调了一个晚上,捂脸= =

2016-11-17 07:52:50

【NOIP 2012 疫情控制】***的更多相关文章

  1. NOIP 2012 疫情控制(二分+贪心+倍增)

    题解 二分时间 然后一个显然的事是一个军队向上爬的越高它控制的点越多 所以首先军队尽量往上爬. 当一个军队可以爬到根节点我们记录下它的剩余时间T和它到达根结点时经过的根节点的子节点son. 当一个军队 ...

  2. 基础算法(二分,贪心):NOIP 2012 疫情控制

    题目大意 给出一棵n个节点的树,根是1,要在除根节点以外的点建立检查点,使得从每条根到叶子的路径上都至少存在一个检查点.检查点由军队来建立.初始军队的位置是给定的,移动军队走一条边需要花费这条边的权值 ...

  3. noip 2012 疫情控制

    /* 考试的时候没想出正解 也没打暴力 时间不够了 随便yy了几种情况按出现的先后顺序处理而没有贪心 的了20分 不粘了 正解是围绕首都的儿子来搞的 显然先二分答案 对于每个限定的最大时间 我们尝试着 ...

  4. 【NOIP】提高组2012 疫情控制

    [题意]n个点的树,1为根,要求删除一些点使得截断根节点和所有叶子结点的路径(不能删根,可以删叶子).有m支军队在m个点上,每时刻所有军队可以走一步,最终走到的地方就是删除的点,求最短时间. [算法] ...

  5. Codevs 1218 疫情控制 2012年NOIP全国联赛提高组

    1218 疫情控制 2012年NOIP全国联赛提高组 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description H 国有 n 个城市,这 ...

  6. 疫情控制 2012年NOIP全国联赛提高组(二分答案+贪心)

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

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

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

  8. [NOIP2012] day2 T3疫情控制

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

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

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

随机推荐

  1. asp图片化电话号码,避免蜘蛛之类爬走用户隐私

    作用:将页面中的电话号码生成图片格式.挺多的分类信息类网站使用这个功能.不用真正的生成图片.原理类似验证码,挺不错的. <% Call Com_CreatValidCode(Request.Qu ...

  2. C#学习笔记10:Try-catch的用法和引用类型、值类型整理

    Try-Catch: 将可能发生异常的代码放到try中,在catch中进行捕获. 如果try中有一行代码发生了异常,那么这行代码后面的代码不会再被执行了. Try写完了以后,紧接着就要写Catch   ...

  3. 【转】关于C#使用Excel的数据透视表的例子

    收到消息,下星期又有导出 Excel 报表的代码要写.心想,不就是 OleDb 先 CREATE 表, 然后 INSERT 么?都是体力活啊...... 结果拿到纸张的报表,我就悲剧了.报表的结构,像 ...

  4. ASP.NET Web Forms 4.5的新特性

    作者:Parry出处:http://www.cnblogs.com/parry/ 一.强类型数据控件 在出现强类型数据控件前,我们绑定数据控件时,前台一般使用Eval或者DataBinder.Eval ...

  5. sql server 查询字符串指定字符出现的次数

    这里提取指定符串"A"在字段中的出现次数SQL为: select len(keyword)-len(replace(keyword, 'A', ' ')) from 表 原理:用r ...

  6. ###STL学习--vector

    点击查看Evernote原文. #@author: gr #@date: 2014-08-11 #@email: forgerui@gmail.com vector的相关问题.<stl学习> ...

  7. XMPP即时通讯(代码实现)

    1.配置XMPP(XMPPConfig.m) 2.配置XMPPFramework框架 3.创建单例类(XMPPManager.h/XMPPManager.m)管理器 XMPPManager.m: #i ...

  8. nodejs学习[持续更新]

    1.退出node process.exit(0) 2.把API从上往下全部看一遍,先混个眼熟. 3. end

  9. 自己写的Python数据库连接类和sql语句拼接方法

    这个工具类十分简单和简洁. sql拼接方法 # encoding=utf-8 from django.http import HttpResponse from anyjson import seri ...

  10. java项目使用的DBhelper类

    import java.io.*; import java.sql.*; import java.util.*; import javax.servlet.jsp.jstl.sql.*; public ...