题目:

题目背景

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. freebsd自动获取ip地址

    最小化安装完成freebsd后,ifconfig查看不到ip地址 修改/etc/rc.conf 添加ifconfig_网卡名称="DHCP" 重启服务器或者sh /etc/rc.c ...

  2. codevs 1606 台阶

    时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 话说某牛家门外有一台阶,这台阶可能会很高(总层数<=1000000). 这 ...

  3. Linux配置临时IP地址

    # ifconfig 查看网卡信息,如下图所示: # ifconfig eth0 192.168.0.107 eth0表示第一块网卡,Linux中所有的设配都是文件,所以eth0是第一块网卡的文件名, ...

  4. 【Codeforces #228】Solutions

    http://codeforces.com/contest/389 重新把号刷到Div 1 准备ACM?(我这么菜还是玩玩算了……) 官方题解出的很快 Div2 A: 怎么做都行……随便找俩数减就可以 ...

  5. HTTP协议详解-基础知识

    HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.绝大多数的Web开发,都是构建在HTTP协议之上的Web应用. HTTP协议的主要特点可概括如下: 简单: ...

  6. Java多线程编程核心(1)

    Java多线程编程核心(1) 停止线程 本节主要讨论如何更好停止一个线程.停止线程意味着在线程处理完成任务之前放弃当前操作. 1.停不了的线程 可能大多数同学会使用interrupt()来停止线程,但 ...

  7. touch-action css属性 滚动和缩放手势

    CSS 属性 touch-action 用于指定某个给定的区域是否允许用户操作,以及如何响应用户操作(比如浏览器自带的划动,缩放等) 默认情况下,平移(滚动) 和 缩放手势由浏览器专门处理.该属性用于 ...

  8. CF-1072-C. Cram Time(贪心,数学)

    CF-1072-C. Cram Time http://codeforces.com/contest/1072/problem/C 题意: 第一天有 a 小时,第二天有 b 小时.第 k 个任务需要 ...

  9. cache支持三种pre-fetch方式:normal/pre-fetch1/pre-fetch2-way1/pre-fetch-way2

    1.normal fetch  ----fetch 1 cache line once 2. pre-fetch mode one ---- fetch 3 cache line once 3.pre ...

  10. vfs_caches_init函数解析

    vfs_caches_init函数初始化VFS,下面梳理函数调用流程 start_kernel() -->vfs_caches_init_early(); -->dcache_init_e ...