二分答案,转化成判定所有科学家能否在lim时间内走到安全的地方

考虑网络流,对于每个非叶子节点,S向它连边,容量为该点科学家的人数

对于每个叶子节点,向T连边,容量为该点的容量

对于每个非叶子节点x,枚举它的所有祖先,对于一个祖先y,向y子树中所有与x距离不超过lim的点连边,容量为inf

由于数据随机,所以树的高度期望为$O(\log n)$

可以先对于每个点把该点子树内所有叶子节点按距离排序,然后第i小的点向第i-1小的点连边

每次查询时只要二分找到最大的满足条件的点然后向该点连边即可

如此建图,点数和边数均为$O(n\log n)$

 

#include<cstdio>
#include<algorithm>
const int N=10010,M=100010,inf=~0U>>2;
int n,i,j,x,y,sum,a[N],b[N],f[N],w[N],G[N],v[N],nxt[N],ed,dis[N];
int st[N],en[N],q[M],m,S,T,h[M],gap[M],maxflow,l,r=500000,mid,ans;
int g[M],d[M],cur;
struct E{int t,f,nxt;E(){}E(int _t,int _f,int _nxt){t=_t,f=_f,nxt=_nxt;}}e[1500000];
inline bool cmp(int x,int y){return dis[x]<dis[y];}
inline void addedge(int x,int y,int z){f[y]=x;w[y]=z;v[++ed]=y;nxt[ed]=G[x];G[x]=ed;}
void dfs2(int x){
if(!a[x])q[++m]=x;
for(int i=G[x];i;i=nxt[i])dfs2(v[i]);
}
void dfs(int x){
if(!a[x])return;
for(int i=G[x];i;i=nxt[i])dis[v[i]]=dis[x]+w[v[i]],dfs(v[i]);
st[x]=m+1;
for(int i=G[x];i;i=nxt[i])dfs2(v[i]);
en[x]=m;
std::sort(q+st[x],q+m+1,cmp);
}
inline int min(int x,int y){return x<y?x:y;}
inline void add(int s,int t,int f){
e[++cur]=E(t,f,g[s]);g[s]=cur;
e[++cur]=E(s,0,g[t]);g[t]=cur;
}
int sap(int v,int flow){
if(v==T)return flow;
int rec=0;
for(int p=d[v];p;p=e[p].nxt)if(h[v]==h[e[p].t]+1&&e[p].f){
int ret=sap(e[p].t,min(flow-rec,e[p].f));
e[p].f-=ret;e[p^1].f+=ret;d[v]=p;
if((rec+=ret)==flow)return flow;
}
if(!(--gap[h[v]]))h[S]=T;
gap[++h[v]]++;d[v]=g[v];
return rec;
}
bool check(int lim){
for(cur=i=1;i<=T;i++)g[i]=d[i]=h[i]=gap[i]=0;
for(i=n+1;i<=m;i++)add(i,q[i],inf);
for(i=1;i<=n;i++)if(a[i]){
add(S,i,b[i]);
for(j=i;j;j=f[j])if(dis[q[st[j]]]<=lim+dis[j]*2-dis[i]){
int l=st[j]+1,r=en[j],mid,t=st[j];
while(l<=r)if(dis[q[mid=(l+r)>>1]]<=lim+dis[j]*2-dis[i])l=(t=mid)+1;else r=mid-1;
add(i,t,inf);
}
for(j=st[i];j<en[i];j++)add(j+1,j,inf);
}else add(i,T,b[i]);
for(gap[maxflow=0]=T,i=1;i<=T;i++)d[i]=g[i];
while(h[S]<T)maxflow+=sap(S,inf);
return maxflow==sum;
}
int main(){
scanf("%d",&n);
for(i=1;i<=n;i++){
for(scanf("%d",&a[i]),j=0;j<a[i];j++)scanf("%d%d",&x,&y),addedge(i,x,y);
scanf("%d",&b[i]);
if(a[i])sum+=b[i];
}
for(m=n,i=1;i<=n;i++)if(!f[i])dfs(i);
S=m+1,T=S+1;
while(l<=r)if(check(mid=(l+r)>>1))r=(ans=mid)-1;else l=mid+1;
return printf("%d",ans),0;
}

  

BZOJ3459 : Bomb的更多相关文章

  1. HDU3555 Bomb[数位DP]

    Bomb Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submi ...

  2. Leetcode: Bomb Enemy

    Given a 2D grid, each cell is either a wall 'W', an enemy 'E' or empty '0' (the number zero), return ...

  3. HDU 5934 Bomb(炸弹)

    p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-s ...

  4. hdu 3622 Bomb Game(二分+2-SAT)

    Bomb Game Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  5. Bomb

    Description The counter-terrorists found a time bomb in the dust. But this time the terrorists impro ...

  6. CF 363B One Bomb(枚举)

    题目链接: 传送门 One Bomb time limit per test:1 second     memory limit per test:256 megabytes Description ...

  7. hdu3555 Bomb (记忆化搜索 数位DP)

    http://acm.hdu.edu.cn/showproblem.php?pid=3555 Bomb Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  8. [HDU3555]Bomb

    [HDU3555]Bomb 试题描述 The counter-terrorists found a time bomb in the dust. But this time the terrorist ...

  9. hdu 5934 Bomb

    Bomb Problem Description There are N bombs needing exploding.Each bomb has three attributes: explodi ...

随机推荐

  1. nodemon:让node自动重启

    nodemon:服务器自动重启工具 当我们修改代码时,node必须要手动重启,但可以按照nodemon. npm install -g nodemon 安装完 nodemon 后,就可以用 nodem ...

  2. Automate Tdxw

    Automate trade module in Tdxw Code # coding: utf-8 """ Created on Thu Dec 07 10:57:45 ...

  3. html5 canvas旋转+缩放

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. MySQL忘记密码了怎么办?

    接手一个项目时,如果上一位负责人没有把项目文档.账号密码整理好是一件很头疼的事情.. 例如,当你想打开MySQL数据库的时候 输入: mysql -u root -p 一回车想输入密码,发现密码错误! ...

  5. c++刷题(39/100)笔试题3

    题目1: 现在你需要用一台奇怪的打字机书写一封书信.信的每行只能容纳宽度为100的字符,也就是说如果写下某个字符会导致行宽超过100,那么就要另起一行书写 信的内容由a-z的26个小写字母构成,而每个 ...

  6. NOI2001 方程的解数(双向搜索)

    solution 一道非常经典的双向搜索题目,先将前3个未知数枚举一遍得到方程的前半部分所有可能的值,取负存入第一个队列中再将后3个未知数枚举一遍,存入第二个队列中.这样我们只要匹配两个队列中相同的元 ...

  7. 如何使用gifsicle压缩gif图片

    最近我写了一些关于如何将各种形式的多媒体格式相互转换的文章,特别是GIF动图方面的,比如如何将小视频转换成GIF动图或将GIF动图转换成视频,有很多像ImageMagick,ffmpeg这样的工具帮助 ...

  8. Javascript - Vue - 请求

    本地增删查的一个例子 <div id="box">    <div class="panel panel-primary">       ...

  9. mybatis动态sql——(六)

    0     什么是动态sql mybatis核心 对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接.组装. 通过mybatis提供的各种标签方法实现动态拼接sql.

  10. 使用配置文件启动MongoDB

    Ubuntu 16.04 (阿里云ECS),MongoDB 4.0, 原来,已经写了10篇MongoDB的随笔了.可是,自己居然没有使用配置文件启动过MongoDB,对其更多的配置是不明白的. 昨天( ...