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

时间限制: 2 s

空间限制: 128000 KB

题目等级 : 钻石 Diamond

题目描述 Description

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

H 国的首都爆发了一种危害性极高的传染病。当局为了控制疫情,不让疫情扩散到边境城市(叶子节点所表示的城市),决定动用军队在一些城市建立检查点,使得从首都到边境城市的每一条路径上都至少有一个检查点,边境城市也可以建立检查点。但特别要注意的是,首都是不能建立检查点的。

现在,在 H国的一些城市中已经驻扎有军队,且一个城市可以驻扎多个军队。一支军队可以在有道路连接的城市间移动,并在除首都以外的任意一个城市建立检查点,且只能在一个城市建立检查点。一支军队经过一条道路从一个城市移动到另一个城市所需要的时间等于道路的长度(单位:小时)。

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

输入描述 Input Description

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

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

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

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

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

的城市的编号。

输出描述 Output Description

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

样例输入 Sample Input

4

1 2 1

1 3 2

3 4 3

2

2 2

样例输出 Sample Output

3

数据范围及提示 Data Size & Hint

【输入输出样例说明】

第一支军队在 2 号点设立检查点,第二支军队从 2 号点移动到 3 号点设立检查点,所需时间为 3 个小时。

【数据范围】

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

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

对于 40%的数据,2 ≤n≤50,0

  1. /*
  2. 这题太好了!!!
  3. 二分+lca+贪心策略.
  4. 二分[1,∑w].
  5. 先dfs序+lca处理出各点关系.
  6. 然后二分检验.
  7. 贪心策略:
  8. (1)向上走更优.
  9. (2)排序后能最大匹配.
  10. 我们先来考虑几种情况
  11. (1)这个军队能够蹦到根节点.
  12. 我们处理出蹦到根节点后剩余的时间.
  13. (2)这个军队蹦不到根节点
  14. 我们尽量让他往上蹦.
  15. 然后向上传标记.
  16. 最后只需要扫根节点的儿子就可以了.
  17. */
  18. #include<iostream>
  19. #include<cstdio>
  20. #include<cstring>
  21. #include<algorithm>
  22. #define MAXN 50001
  23. #define D 20
  24. using namespace std;
  25. int fa[MAXN][D+5],deep[MAXN],son[MAXN],head[MAXN],n,m,dis[MAXN],a[MAXN],tot,ans=1e9,top,cut,sum;
  26. bool b[MAXN];
  27. struct data{int v,u;}s[MAXN],c[MAXN];
  28. struct egde{int v,next,x;}e[MAXN*2];
  29. int read()
  30. {
  31. int x=0,f=1;char ch=getchar();
  32. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  33. while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
  34. return x*f;
  35. }
  36. void add(int u,int v,int z)
  37. {
  38. e[++tot].v=v;
  39. e[tot].x=z;
  40. e[tot].next=head[u];
  41. head[u]=tot;
  42. }
  43. bool cmp(const data &x,const data &y)
  44. {
  45. return x.v<y.v;
  46. }
  47. void dfs(int now,int father,int d)
  48. {
  49. fa[now][0]=father;
  50. for(int i=head[now];i;i=e[i].next)
  51. {
  52. if(father!=e[i].v)
  53. {
  54. dis[e[i].v]=dis[now]+e[i].x;
  55. dfs(e[i].v,now,d+1);
  56. }
  57. }
  58. }
  59. void get_father()
  60. {
  61. for(int j=1;j<=20;j++)
  62. for(int i=1;i<=n;i++)
  63. fa[i][j]=fa[fa[i][j-1]][j-1];
  64. }
  65. void slove(int u,int fa)
  66. {
  67. bool flag=false,p=1;
  68. for(int i=head[u];i;i=e[i].next)
  69. {
  70. int v=e[i].v;
  71. if(fa!=v)
  72. slove(v,u),p&=b[v],flag=true;
  73. }
  74. if(flag&&p&&u!=1) b[u]=true;return ;
  75. }
  76. bool check(int x)
  77. {
  78. memset(b,0,sizeof(b));
  79. int father=0;top=0,cut=0;
  80. for(int i=1;i<=m;i++)
  81. {
  82. int now=a[i],d=0;
  83. if(dis[now]<x)
  84. father=1;
  85. else for(int j=20;j>=0;j--)
  86. {
  87. if(fa[now][j]&&dis[now]-dis[fa[now][j]]<=x)
  88. {
  89. father=fa[now][j];
  90. d=dis[now]-dis[fa[now][j]];
  91. break;
  92. }
  93. }
  94. if(father!=1) b[father]=true;
  95. else
  96. {
  97. s[++top].v=x-dis[now];
  98. for(int j=20;j>=0;j--)
  99. if(fa[now][j]>1)
  100. now=fa[now][j];
  101. s[top].u=now;
  102. }
  103. }
  104. slove(1,0);
  105. for(int i=head[1];i;i=e[i].next)
  106. if(!b[e[i].v])
  107. c[++cut].u=e[i].v,c[cut].v=e[i].x;
  108. sort(s+1,s+top+1,cmp),sort(c+1,c+cut+1,cmp);
  109. int j=1;c[cut+1].v=1e9;
  110. for(int i=1;i<=top;i++)
  111. {
  112. if(!b[s[i].u]) b[s[i].u]=true;
  113. else if(s[i].v>=c[j].v) b[c[j].u]=true;
  114. while(b[c[j].u]) j++;
  115. }
  116. return j>cut;
  117. }
  118. void erfen(int ll,int rr)
  119. {
  120. int mid;
  121. while(ll<=rr)
  122. {
  123. mid=(ll+rr)>>1;
  124. if(check(mid)) ans=mid,rr=mid-1;
  125. else ll=mid+1;
  126. }
  127. }
  128. int main()
  129. {
  130. int x,y,z;
  131. n=read();
  132. for(int i=1;i<n;i++)
  133. {
  134. x=read(),y=read();z=read();
  135. add(x,y,z);sum+=z;add(y,x,z);
  136. }
  137. m=read();
  138. for(int i=1;i<=m;i++)
  139. a[i]=read();
  140. dfs(1,0,0);
  141. get_father();
  142. erfen(1,sum);
  143. if(ans==1e9) printf("-1");
  144. else printf("%d\n",ans);
  145. return 0;
  146. }

Codevs 1218 疫情控制 2012年NOIP全国联赛提高组的更多相关文章

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

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

  2. Codevs 1217 借教室 2012年NOIP全国联赛提高组

    1217 借教室 2012年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在大学期间,经常需要租借教 ...

  3. Codevs 1198 国王游戏 2012年NOIP全国联赛提高组

    1198 国王游戏 2012年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 恰逢 H 国国庆,国王邀 ...

  4. Codevs 1200 同余方程 2012年NOIP全国联赛提高组

    1200 同余方程 2012年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 求关于 x 同余方程 a ...

  5. 开车旅行 2012年NOIP全国联赛提高组(倍增+set)

    开车旅行 2012年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond     题目描述 Description 小A 和小B决定利用 ...

  6. Codevs 3286 火柴排队 2013年NOIP全国联赛提高组 树状数组,逆序对

    题目:http://codevs.cn/problem/3286/ 3286 火柴排队  2013年NOIP全国联赛提高组  时间限制: 1 s   空间限制: 128000 KB   题目等级 : ...

  7. Codevs 1069 关押罪犯 2010年NOIP全国联赛提高组

    1069 关押罪犯 2010年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description S 城现有两座监狱,一共 ...

  8. Codevs 3731 寻找道路 2014年 NOIP全国联赛提高组

    3731 寻找道路 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 在有向图G中,每条边的长度均为1,现给定起点和终点,请你在图中找 ...

  9. Codevs 3287 货车运输 2013年NOIP全国联赛提高组(带权LCA+并查集+最大生成树)

    3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description A 国有 n 座 ...

随机推荐

  1. C++ 构造过程和析构过程

    1.C++构造和析构的过程,类似于穿衣脱衣的过程.穿衣是:先穿内衣,再穿外套.脱衣是:先脱外套,再脱内衣.C++构造过程:首先调用父类构造方法,再调用子类构造方法.C++析构过程:首先调用子类析构方法 ...

  2. C++ 构造和析构

    1.继承关系可认为,子类在父类的基础上进行.从这个角度讲,可把它认为穿衣脱衣的过程.穿衣是:先穿内衣,再穿外套.脱衣是:先脱外套,在脱内衣.构造是:先调用父类构造方法,再调用子类构造方法.析构是:先调 ...

  3. git克隆远程项目分支到本地对应分支

    最近公司改用git了,研究了一下如何把远程的代码克隆到本地. 1. 配置对应信息 git config --global user.name git config --global user.emai ...

  4. ExtJs自学教程(1):一切从API開始

    题 记 该系列文章不側重全方位的去介绍ExtJs的使用,仅仅是側重于解决ExtJs问题的思考方法.写的人不用长篇大论,学的人则可以自立更生.l  学习的人仅仅要有一些CSS的javascript的基础 ...

  5. iOS-推送通知

    推送通知可以做3件事:(1)文字信息(2)一种声音 (3)一个徽章的标记号(第几条消息..) 推送通知流程  (app应用程序--->iOS 设备--->APNS(apple服务器)--- ...

  6. Android TabHost TabWidget 去除黑线(底部下划线)

    采用TabHost布局时,往往会发现默认的系统风格与软件风格很不协调,比如TabWidget的下划线影响布局效果.通常情况下会去除其下划线.如果是采用xml布局文件,在TabWidget的属性项设置a ...

  7. 浅谈ASP脚本的解释

    10多年前,ASP的出现使全世界的WEB设计者摆脱了C/C++的繁杂,大幅提升了页面的开发效率 然而一直到数年之后,asp的解释一直握在微软手里,后来阿帕奇也支持asp了,虽然没有IIS那么强大,但是 ...

  8. oracle中对LONG列进行查询

    SQL> CREATE TABLE T_LONG (ID NUMBER, LONG_COL LONG); 表已创建. SQL> INSERT INTO T_LONG VALUES (1, ...

  9. 我的开发框架(WinForm)4

    日志模块 对于一个系统来说,日志模块是必不可少的,它能给后面系统的维护和bug的修复,带来极大的方便..net的日志模块有很多,比较流行的有Log4Net,NLog,还有微软企业库的日志模块,我采用的 ...

  10. PowerShell 批量增加ACL

    $serviceName="云服务名称"$vmName="虚拟机名称"$endPoint="终结点名称"$acl=New-AzureAclC ...