Description

H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是树中的根节点。
H 国的首都爆发了一种危害性极高的传染病。当局为了控制疫情,不让疫情扩散到边境
城市(叶子节点所表示的城市),决定动用军队在一些城市建立检查点,使得从首都到边境
城市的每一条路径上都至少有一个检查点,边境城市也可以建立检查点。但特别要注意的是, 首都是不能建立检查点的。
现在,在 H
国的一些城市中已经驻扎有军队,且一个城市可以驻扎多个军队。一支军队可以在有道路连接的城市间移动,并在除首都以外的任意一个城市建立检查点,且只能在
一个城市建立检查点。一支军队经过一条道路从一个城市移动到另一个城市所需要的时间等 于道路的长度(单位:小时)。
请问最少需要多少个小时才能控制疫情。注意:不同的军队可以同时移动。

Input

第一行一个整数 n,表示城市个数。
接下来的 n-1 行,每行 3 个整数,u、v、w,每两个整数之间用一个空格隔开,表示从 城市 u 到城市 v 有一条长为 w 的道路。数据保证输入的是一棵树,且根节点编号为 1。
接下来一行一个整数 m,表示军队个数。
接下来一行 m 个整数,每两个整数之间用一个空格隔开,分别表示这 m 个军队所驻扎 的城市的编号。

Output

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

Sample Input

4
1 2 1
1 3 2
3 4 3
2
2 2

Sample Output

3

Hint

样例说明:
第一支军队在 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

 
思路
1.显而易见的性质:一个军队站得深度越小,产生的作用越大  (根节点除外)
  -->尽量把点往上提  -->倍增优化
2.题目求的是 时间中最长的最小值
  -->最大/小的最小/大值常用二分答案
3.由于1中提到根节点不能放,所以 以 根节点的某个子节点 为根的子树可能不能被覆盖
  -->考虑子树间的军队移动
4.对于某个军队
  如果最高不能到达根节点,根据性质1,设在能在的最高点
  如果能到根节点,记录能继续走的距离(所有的从大到小排序)
5.扫描所有 以 根节点的某个子节点 为根的子树,记录下没有被覆盖的子树(记录子树的根,也就是根的子节点i),按i到root的距离从大到小排序
6.对于每一个不能被覆盖的子树的根节点,如果子树中有能到达子树根节点的军队,根据贪心,选能继续走的距离最小的军队抵消(类似田忌赛马)
如果没有,拿继续走的距离最小的军队抵消(反正已经从大到小排好序了)
7.AC
 
代码
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define RG register ll
#define rep(i,a,b) for(RG i=a;i<=b;i++)
#define per(i,a,b) for(RG i=a;i>=b;i--)
#define ll long long
#define inf (1<<30)
#define maxn 50005
using namespace std;
ll n,m,cnt,cnta,cntb;
ll head[maxn],st[maxn];
ll fa[maxn][],dis[maxn][];
ll minid[maxn],fumin[maxn],resmin[maxn];
bool vis[maxn],used[maxn];
struct E{
ll v,next,val;
}e[maxn<<];
struct Dat{
ll id;ll res;
inline bool operator < (const Dat &tmp)const{
return res>tmp.res;
}
}a[maxn],b[maxn];
inline ll read()
{
ll x=,f=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} inline void add()
{
RG u=read(),v=read(),val=read();
e[++cnt].v=v,e[cnt].next=head[u],e[cnt].val=val,head[u]=cnt;swap(u,v);
e[++cnt].v=v,e[cnt].next=head[u],e[cnt].val=val,head[u]=cnt;
} void Pre_dfs(ll u,ll pa,ll val)
{
fa[u][]=pa,dis[u][]=val;
for(ll j=;j<=;j++)
fa[u][j]=fa[fa[u][j-]][j-],dis[u][j]=dis[u][j-]+dis[fa[u][j-]][j-];
for(ll i=head[u];i;i=e[i].next)
if(e[i].v!=pa) Pre_dfs(e[i].v,u,e[i].val);
} bool cover(ll u,ll pa)
{
bool flg=,leaf=;
if(vis[u]) return ;
for(ll i=head[u];i;i=e[i].next)
{
ll v=e[i].v;if(v==pa) continue;
leaf=;
if(!cover(v,u))
{
flg=;
if(u==) b[++cntb].id=v,b[cntb].res=e[i].val;
else return ;
}
}
if(leaf) return ;
return flg;
} bool check(ll lim)
{
memset(fumin,,sizeof(fumin));
memset(used,,sizeof(used));
memset(vis,,sizeof(vis));
cnta=cntb=;
rep(i,,m)
{
ll x=st[i],cost=;
per(j,,)
if(fa[x][j]>&&cost+dis[x][j]<=lim)
cost+=dis[x][j],x=fa[x][j];
if(fa[x][]==&&cost+dis[x][]<=lim)
{
a[++cnta].res=lim-dis[x][]-cost;
a[cnta].id=i;
if(!fumin[x]||a[cnta].res<resmin[x])
fumin[x]=i,resmin[x]=a[cnta].res;
}
else vis[x]=;
}
if(cover(,)) return ;
sort(a+,a++cnta);
sort(b+,b++cntb);
ll now=;used[]=;
rep(i,,cntb)
{
if(!used[fumin[b[i].id]])
{used[fumin[b[i].id]]=;continue;}
while(now<=cnta&&(used[a[now].id]||a[now].res<b[i].res)) ++now;
if(now>cnta) return ;
used[a[now].id]=;
}
return ;
} int main()
{
n=read();
rep(i,,n) add();
m=read();
rep(i,,m) st[i]=read();
Pre_dfs(,,);
ll l=,r=,mid,ans;
while(l<=r)
{
mid=(l+r)>>;
if(check(mid)) ans=mid,r=mid-;
else l=mid+;
}
cout<<ans;
return ;
}

疫情控制 [NOIP2012]的更多相关文章

  1. 洛谷P1084 疫情控制 [noip2012] 贪心+树论+二分答案 (还有个小bugQAQ

    正解:贪心+倍增+二分答案 解题报告: 正好想做noip的题目然后又想落实学长之前讲的题?于是就找上了这题 其实之前做过,70,然后实在细节太多太复杂就不了了之,现在再看一遍感觉又一脸懵了... 从标 ...

  2. 【NOIP2012】 疫情控制

    [NOIP2012] 疫情控制 标签: 倍增 贪心 二分答案 NOIP Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...

  3. Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增)

    Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增) Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...

  4. [NOIP2012]疫情控制 贪心 二分

    题面:[NOIP2012]疫情控制 题解: 大体思路很好想,但是有个细节很难想QAQ 首先要求最大时间最小,这种一般都是二分,于是我们二分一个时间,得到一个log. 然后发现一个军队,越往上走肯定可以 ...

  5. NOIP2012 疫情控制 题解(LuoguP1084)

    NOIP2012 疫情控制 题解(LuoguP1084) 不难发现,如果一个点向上移动一定能控制更多的点,所以可以二分时间,判断是否可行. 但根节点不能不能控制,存在以当前时间可以走到根节点的点,可使 ...

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

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

  7. 疫情控制 blockade

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

  8. CH6301 疫情控制

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

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

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

随机推荐

  1. 2019-3-9,Servlet转跳链接详解

    //以下代码,可以传递request和response对象及其属性和变量至指定页面 request.getRequestDispatcher("showAttribut.jsp") ...

  2. 005-Python字典

    Python字典(dict) 字典是另一种可变容器模型,且可存储任意类型对象. 字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号{}中: ...

  3. Quartz.NET(任务调度)与Topshelf(服务)的综合使用

    http://www.cnblogs.com/jys509/p/4628926.html http://cron.qqe2.com/ Quartz_Topshlf_Demo.7z

  4. jquery自定义事件

    触发事件: $(document).trigger('REMOVE_WEBSITE_MSG'); 判断消息条数为0,触发这个

  5. 「BZOJ3791」作业

    题解: 比正解的做法要复杂 正解直接确定了最多有2k-1段 并且可以证明2k-1是一定可以覆盖的 于是可以直接dp 我的想法是先覆盖一段黑的,然后白的覆盖上去 所以f[i][0/1/2][0/1/2] ...

  6. 记JS一个错误,

    在定义变量时候,如果直接定义 var obj=null;那么,在转码时候,比如转为base64,此时或出现特殊的文字(也是汉字,只是很少见少用的文字,而且,出现的文字是根据你给obj赋值决定的,) 由 ...

  7. nginx的with-http_sub_module模块使用之替换字符串

    一.介绍 该ngx_http_sub_module模块是一个过滤器,通过将一个指定的字符串替换为另一个字符串来修改响应.该模块不是默认生成的,它应该使用--with-http_sub_module 配 ...

  8. python全栈开发day66-视图系统、路由系统

    一.昨日内容回顾 1. tags 1. for循环 {% for name in name_list %} {{ name }} {% endfor %} {% for name in name_li ...

  9. Codeforces 354B dp Game with Strings dp

    Game with Strings 题意并不是在图上走,看了好久才看出来.. dp[ i ][ mask ]表示从 i 层开始走,起点有mask个, a的个数-b的个数的  最大值或者最小值. #in ...

  10. websocket/dwebsocket 实现前后端的实时通信

    1.  用bottle框架,自己写一个服务端实现: 转载   :http://www.linuxyw.com/813.html 功能:用websocket技术,在运维工具的浏览器上实时显示远程服务器上 ...