NOIP2012DAY2T3【疫情控制】
来源:互联网 发布:软件著作权的好处 编辑:程序博客网 时间:2024/05/02 04:35
Description
H国有n个城市,这n个城市用n-1条双向道路相互连通构成一棵树,1号城市是首都,也是树中的根节点。 H国的首都爆发了一种危害性极高的传染病。当局为了控制疫情,不让疫情扩散到边境城市(叶子节点所表示的城市),决定动用军队在一些城市建立检查点,使得从首都到边境城市的每一条路径上都至少有一个检查点,边境城市也可以建立检查点。但特别要注意的是,首都是不能建立检查点的。 现在,在H国的一些城市中已经驻扎有军队,且一个城市可以驻扎多个军队。一支军队可以在有道路连接的城市间移动,并在除首都以外的任意一个城市建立检查点,且只能在一个城市建立检查点。一支军队经过一条道路从一个城市移动到另一个城市所需要的时间等于道路的长度(单位:小时)。 请问最少需要多少个小时才能控制疫情。注意:不同的军队可以同时移动。
Input Format
第一行一个整数n,表示城市个数。 接下来的n-1行,每行3个整数,u、v、w,每两个整数之间用一个空格隔开,表示从城市u到城市v有一条长为w的道路。数据保证输入的是一棵树,且根节点编号为1。 接下来一行一个整数m,表示军队个数。 接下来一行m个整数,每两个整数之间用一个空格隔开,分别表示这m个军队所驻扎的城市的编号。
Output Format
共一行,包含一个整数,表示控制疫情所需要的最少时间。如果无法控制疫情则输出-1。
Sample Input
4 1 2 1 1 3 2 3 4 3 2 2 2
Sample Output
3
Hint
保证军队不会驻扎在首都。
对于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。
【题解】
#include <algorithm>#include <iostream>#include <cstdlib>#include <cstring>#include <string>#include <cstdio>#include <queue>#include <ctime>#include <vector>using namespace std;int num,i,j,k,m,n,x,y,z,first[50005],up[50005][20],tot,fa[50005],bo[50005],a[50005],line[50005];long long g[50005][20],l,r,mid,ans;struct info { int ar,next,l; }tree[100005];struct army { long long come,last; }arm[50005];struct city { int no,l; }ci[50005];bool cmp1(army x,army y){return x.come<y.come;}bool cmp2(army x,army y){return x.last<y.last;}bool cmp3(city x,city y){return x.no<y.no;}bool cmp4(city x,city y){return x.l<y.l;}void add(int x,int y,int z) { num++;tree[num]=(info){y,first[x],z};first[x]=num; }int getfa(int x) { if (fa[x]==x) return x;else return fa[x]=getfa(fa[x]); }void dfs(int u,int fat) { int i,v,pd=0;fa[u]=u; for (i=first[u];i;i=tree[i].next) { v=tree[i].ar; if (v==fat) continue; dfs(v,u);up[v][0]=u;g[v][0]=tree[i].l;//pd=1; //child[u]+=child[v]; if (u!=1) fa[v]=u; }//if (pd==0) child[v]=1,tot++; }void find(int u,int fat) { int i,v,pd=0; for (i=first[u];i;i=tree[i].next) { v=tree[i].ar; if (v==fat) continue; find(v,u);pd=1; if (bo[v]!=-1&&bo[u]!=-1) bo[u]+=bo[v]; }if (pd==0&&bo[u]!=-1) bo[u]=1; }bool pd(long long mid) { int i,j,l=0,x,sum;long long k;memset(bo,0,sizeof(bo)); for (i=1;i<=m;i++) { k=mid;x=a[i]; for (;g[x][0]<=k;) { for (j=0;g[x][j]<=k;j++);j--; k-=g[x][j];x=up[x][j]; } bo[x]=-1; if (x==1) arm[++l]=(army){getfa(a[i]),k}; }find(1,-1);k=0;for (i=1;i<=l;i++) { if (line[arm[i].come]>arm[i].last&&bo[arm[i].come]>0) bo[arm[i].come]=-1,swap(arm[i],arm[l]),l--,i--; }for (i=first[1];i;i=tree[i].next) if (bo[tree[i].ar]>0) ci[++k]=(city){tree[i].ar,tree[i].l};sort(arm+1,arm+l+1,cmp2);sort(ci+1,ci+k+1,cmp4);for (j=i=1,sum=0;j<=k;j++) for (;i<=l;i++) if (arm[i].last>=ci[j].l) { i++;sum++;break; } if (sum==k) return 1;else return 0; }int main() { scanf("%d",&n); for (i=1;i<n;i++) scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z); up[1][0]=1;g[1][0]=1e15;dfs(1,-1); for (i=1;i<19;i++) for (j=1;j<=n;j++) { up[j][i]=up[up[j][i-1]][i-1]; g[j][i]=g[j][i-1]+g[up[j][i-1]][i-1];}l=0;r=1e15;for (i=first[1];i;i=tree[i].next) line[tree[i].ar]=tree[i].l;scanf("%d",&m);for (i=1;i<=m;i++) scanf("%d",&a[i]);ans=-1;for (;l<=r;) { mid=(l+r)/2; if (pd(mid)) ans=mid,r=mid-1;else l=mid+1; }printf("%lld",ans); }
- NOIP2012DAY2T3【疫情控制】
- 疫情控制
- 疫情控制
- 疫情控制
- 【思维】NOIP2012疫情控制
- NOIP2012 疫情控制
- JZOJ 3104.疫情控制
- P1084 疫情控制
- noip2012疫情控制
- P1084 疫情控制
- NOIP 2012 疫情控制
- 洛谷 P1084 疫情控制
- codevs1218: [NOIP2012]疫情控制
- 【NOIP2012】Day2T3 疫情控制
- 洛谷 P1084 疫情控制
- NOIP2012 疫情控制
- [NOIP2012]疫情控制
- 【jzoj3104】【疫情控制】
- js数组依据下标删除元素
- 二叉树(二)——三种遍历算法的非递归实现(java版)
- html的meta总结,html标签中meta属性使用介绍
- JAVA构造方法私有化
- Python将文本去空格并保存到txt文件中
- NOIP2012DAY2T3【疫情控制】
- SCPPO(二十七):技术盛宴—报表交流会
- 填词
- Android:基础控件之(一)Button
- 2016年中国大学生程序设计竞赛(杭州)-重现赛
- ActionContextCleanUp作用
- QT打包程序(程序安装与部署)含数据库、打印、等不能正常运行的解决方案
- spring基本配置详解(属性bean的基本配置)
- orcal 语句触发器和行触发器的区别