题目:

题目背景

NOIP2012 提高组 DAY2 试题。

题目描述

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 2 1 
1 3 2 
3 4 3 

2 2

输出

3

备注

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

【数据范围】
保证军队不会驻扎在首都。
对于 20%  的数据,2≤n≤10;
对于 40%  的数据,2≤n≤50,0<w<105;
对于 60%  的数据,2≤n≤1000,0<w<106;
对于 80%  的数据,2≤n≤10,000;
对于 100% 的数据,2≤m≤n≤50,000,0<w<109。

题解:

贪心的妙用····表示一道题先根据题意找到基本策略真的很重要

首先要明白,将军队在不超时的情况下往根节点移动越多控制的叶子节点肯定是越多的。

因此先二分答案,然后在答案的限制下尽量将所有军队往根节点移动(因为一个军队越靠近根节点控制的叶节点肯定越多)

然后通过递归(注意这里递归是如果一个节点的所有儿子都被军队占领了,相当于它一个节点被占领,这样递归从叶子节点到根节点层层染色)找到根节点(1号)的哪些儿子还需要军队来占领(因为如果根节点的儿子还未被占领,则儿子所在子树的叶子节点肯定还未被控制)

于是那些移动得到根节点的军队就有用处了···首先,如果一个军队在移动到根节点的过程中经过了这些还未被占领的儿子节点中的一个,则用这个军队占领这个儿子节点即可.如果不是,将它们派去占领其他儿子节点(注意这里又会用到一次贪心,将移动到根节点后剩余时间少的军队尽量去占领那些与根节点距离小的儿子节点,总体下来无疑会占领得更多)。

这样的话所算出的占领叶子节点数一定是最多的

没想到这道题考贪心会考这么深···

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cctype>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=5e4+;
int Rint()
{
char c;
int f=;
for(c=getchar();c<''||c>'';c=getchar());
for(;c<=''&&c>='';c=getchar())
f=(f<<)+(f<<)+c-'';
return f;
}
long long Rlong()
{
char c;
long long f=;
for(c=getchar();c<''||c>'';c=getchar());
for(;c<=''&&c>='';c=getchar())
f=(f<<)+(f<<)+c-'';
return f;
}
struct node
{
int point;
long long dis;
}army[N],leftcity[N];
bool visit[N];
bool comp(node x,node y)
{
return x.dis<y.dis;
}
int first[N],next[N*],go[N*],tot,a[N];
long long val[N*],dis[N][];
int n,m,g[N][],deep[N],tota,totl;
void comb(int a,int b,long long c)
{
next[++tot]=first[a],first[a]=tot,go[tot]=b,val[tot]=c;
next[++tot]=first[b],first[b]=tot,go[tot]=a,val[tot]=c;
}
inline void dfs(int u,int fa)
{
for(int e=first[u];e;e=next[e])
{
int v=go[e];
if(v==fa) continue;
g[v][]=u;
deep[v]=deep[u]+;
dis[v][]=val[e];
dfs(v,u);
}
}
inline void color(int u)
{
int t1=,t2=;
for(int e=first[u];e;e=next[e])
{
int v=go[e];
if(v==g[u][]) continue;
color(v);
if(!visit[v]) t1=;
else t2=;
}
if(t1==&&t2==&&u!=) visit[u]=true;
}
inline bool check(long long limit)
{
memset(visit,false,sizeof(visit));
tota=,totl=;
for(int i=;i<=m;i++)
{
long long temp=limit;
int u=a[i];
for(int j=;j>=;j--)
{
if(g[u][j]>=&&temp>=dis[u][j])
{
temp-=dis[u][j];
u=g[u][j];
if(u==)
break;
}
}
if(u!=) visit[u]=true;
else
{
army[++tota].dis=temp;
u=a[i];
for(int j=;j>=;j--)
if(g[u][j]>) u=g[u][j];
army[tota].point=u;
}
}
color();
for(int e=first[];e;e=next[e])
{
if(!visit[go[e]])
{
leftcity[++totl].point=go[e];
leftcity[totl].dis=val[e];
}
}
sort(leftcity+,leftcity+totl+,comp);
sort(army+,army+tota+,comp);
leftcity[totl+].dis=1e+;
int head=;
for(int i=;i<=tota;i++)
{
if(!visit[army[i].point])
visit[army[i].point]=true;
else
{
if(army[i].dis>=leftcity[head].dis)
visit[leftcity[head].point]=true;
}
while(visit[leftcity[head].point]==true)
{
head++;
if(head>totl)
return true;
}
}
return false;
}
int main()
{
//freopen("a.in","r",stdin);
n=Rint();
int A,B;
long long C;
long long left=,right=;
for(int i=;i<n;i++)
{
A=Rint(),B=Rint(),C=Rlong();
comb(A,B,C);
right+=C;
}
m=Rint();
dfs(,);
for(int i=;i<=m;i++) a[i]=Rint();
for(int i=;i<=;i++)
for(int j=;j<=n;j++)
{
g[j][i]=g[g[j][i-]][i-];
dis[j][i]=dis[j][i-]+dis[g[j][i-]][i-];
}
while(left<right)
{
long long mid=(left+right)/;
if(check(mid)) right=mid;
else left=mid+;
}
if(check(left)) cout<<left<<endl;
else cout<<"-1"<<endl;
return ;
}

刷题总结——疫情控制(NOIP2012提高组)的更多相关文章

  1. 刷题总结——子串(NOIP2015提高组)

    题目: 题目背景 NOIP2015 提高组 Day2 T2 题目描述 有两个仅包含小写英文字母的字符串 A 和 B .现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在 ...

  2. 【未完成0.0】Noip2012提高组day2 解题报告

    第一次写一套题的解题报告,感觉会比较长.(更新中Loading....):) 题目: 第一题:同余方程 描述 求关于x的同余方程ax ≡ 1 (mod b)的最小正整数解. 格式 输入格式 输入只有一 ...

  3. GZOJ 1361. 国王游戏【NOIP2012提高组DAY1】

    国王游戏[NOIP2012提高组DAY1] Time Limit:1000MS Memory Limit:128000K Description 国王游戏(game.cpp/c/pas) [问题描述] ...

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

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

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

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

  6. [NOIP2012] 提高组 洛谷P1081 开车旅行

    题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的 城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为 Hi,城市 ...

  7. [NOIP2012] 提高组 洛谷P1080 国王游戏

    题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右 手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排 成一排,国王站在队伍 ...

  8. [NOIP2012] 提高组 洛谷P1083 借教室

    题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借教室的信息,我们自然 ...

  9. [NOIP2012] 提高组 洛谷P1082 同余方程

    题目描述 求关于 x 的同余方程 ax ≡ 1 (mod b)的最小正整数解. 输入输出格式 输入格式: 输入只有一行,包含两个正整数 a, b,用一个空格隔开. 输出格式: 输出只有一行,包含一个正 ...

随机推荐

  1. 介绍hadoop的好文章

    http://www.centoscn.com/image-text/install/2014/1121/4158.html http://www.cnblogs.com/xia520pi/categ ...

  2. UVA 1151 Buy or Build (最小生成树)

    先求出原图的最小生成树,然后枚举买哪些套餐,把一个套餐内的点相互之间边权为0,直接用并查集缩点.正确性是基于一个贪心, 在做Kruskal算法是,对于没有进入最小生成树的边,排序在它前面的边不会减少. ...

  3. 数据库:SQL Server自增长列的编号

    SQL Server表中的自动编号ID重新开始排列 说法一: 有两种方法: 方法1: truncate table 你的表名 --这样不但将数据删除,而且可以重新置位identity属性的字段. 方法 ...

  4. Docker基础内容之网络基础

    网络命名空间基本原理 单机版多容器实例网络交互原理 在宿主机上面打开两张网卡eth0与eth1,打通两张网卡的链路 在test1上面启动一个veth网卡,创建一个namespace:并桥接到eth0上 ...

  5. RedHat7搭建KVM虚拟机

    RedHat7搭建KVM虚拟机 1. 宿主机安装RedHat7.3系统 1.1选择语言 中文.简体中文(中国) 1.2安装位置 1.2.1自定义分区,选择LVM,将分区空间全部分配给根 1.2.2禁用 ...

  6. hihoCoder-1093-SPFA

    SPFA的卓越之处就在于处理多点稀疏图,因为点太多的话,我们直接用矩阵来存图的话是存不下的. 所以当我们用邻接矩阵来存图的话,我们就可以用SPFA来解决这类问题,spfa就是优化版的bellman-f ...

  7. NOIP 2017 D2T1 奶酪

    #include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #i ...

  8. [LUOGU] P1024 选课

    题目描述 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习.现在有N门功课,每门课有个学分,每门课有一 ...

  9. mysql 5.5安装/卸载使用总结

    安装 卸载 1.在控制面板->卸载与更改程序 中卸载mysql 2.删除安装目录下的mysql文件夹 3.删除隐藏文件夹C:\ProgramData\中的MySQL,否则再次安装时会卡在 sta ...

  10. Could not connect to Redis at IP No route to host

    这个问题是在用远程去访问redis出现的 原因:是服务器新装系统  iptables这个的问题 解决办法: sudo iptables -F 轻松解决