标签:2525 ch int 点燃 Poi2011 len inline Dynamite include
Byteotian Cave的结构是一棵N个节点的树,其中某些点上面已经安置了炸药,现在需要点燃M个点上的引线引爆所有的炸药。
某个点上的引线被点燃后的1单位时间内,在树上和它相邻的点的引线会被点燃。如果一个有炸药的点的引信被点燃,那么这个点上的炸药会爆炸。
求引爆所有炸药的最短时间。
好题啊。这种题竟然是“边权相等就贪心,边权不等就dp”。。。
首先二分答案,然后问题就转化成一个点如果点燃它的引线就能覆盖与它距离<=mid的点,求用最少的点来覆盖所有炸药点。关键是边权都为1,所以可以贪心。
f[x]表示在x的子树内未被覆盖的与x距离最远的炸药点距离,g[x]表示在x的子树内与x距离最近的点燃点距离。
如果f[x]+g[x]<=mid,那么就说明x子树内就可以搞定。
如果f[x]==mid,那么就说明x一定要被点燃。
剩下的情况就可以留给祖先处理。
那最后注意一下细节就可以了。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline void write(int x)
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
}
inline void pr1(int x){write(x),putchar(' ');}
inline void pr2(int x){write(x),puts("");}
struct node
{
int x,y,next;
}a[600010];int len,last[300010];
bool v[300010];
inline void ins(int x,int y)
{
len++;
a[len].x=x;a[len].y=y;
a[len].next=last[x];last[x]=len;
}
int n,limit,w;
int f[300010],g[300010];
inline void solve(int x,int fa)
{
g[x]=n,f[x]=0;
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(y==fa)continue;
solve(y,x);
f[x]=max(f[x],f[y]+1);g[x]=min(g[x],g[y]+1);
}if(v[x]==false && !f[x])f[x]=-1;
if(f[x]+g[x]<=limit)f[x]=-1;
else if(f[x]==limit || (x==1 && f[x]>=0)){w++;f[x]=-1,g[x]=0;}
}
int main()
{
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
n=read();int m=read();
for(int i=1;i<=n;i++)v[i]=read();
for(int i=1;i<n;i++){int x=read(),y=read();ins(x,y),ins(y,x);}
int l=0,r=n,ans;
while(l<=r)
{
int mid=(l+r)>>1;limit=mid,w=0;solve(1,0);
if(w<=m)ans=mid,r=mid-1;
else l=mid+1;
}pr2(ans);
return 0;
}
标签:2525,ch,int,点燃,Poi2011,len,inline,Dynamite,include 来源: https://blog.csdn.net/lixuanjing2016/article/details/89789625
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。