bzoj 1189 二分+最大流
思路:
先预处理出每个人到每扇门的时间,用门作为起点进行bfs处理。
然后二分时间,假设时间为x,将每扇门拆成1到x,x个时间点,表示这扇门有几个时间点是可以出去的。对于一扇门,每个时间点都向后一个时间点建边,表示人在当前时间点到达,可以在下一时间点出去。
先将s连上所有的空地,流量为1,建立每个空地每个门的对应的时间点流量为1的边,表示这个空地的人会再某一时间点到达这扇门。然后每个门流向t,流量为inf。只要最大流为空地的数量,则代表该时间是可以的,继续向下二分。
#include<bits/stdc++.h>
#define CLR(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
int fx[][]={{,},{,-},{,},{-,}};
int dis[][][],n,m;
char s[][];
int ed[],g[][],cnt,sum,st,t;
const int maxn=;
const int inf=0x3f3f3f3f;
int head[maxn],tot=;
struct edge{
int to,f,Next;
}a[maxn<<];
void addv(int u,int v,int w){
a[++tot].to=v,a[tot].f=w,a[tot].Next=head[u],head[u]=tot;
a[++tot].to=u,a[tot].f=,a[tot].Next=head[v],head[v]=tot;
}
inline void bfs(int id){
queue<int >q;
dis[id][ed[id]/m][ed[id]%m]=;
q.push(ed[id]);
while(!q.empty()){
int u=q.front();
int x=u/m,y=u%m;
q.pop();
for(int i=;i<;i++){
int xx=x+fx[i][],yy=y+fx[i][];
if(xx<||xx>=n||yy<||yy>=m||s[xx][yy]!='.')continue;
if (dis[id][xx][yy]>dis[id][x][y]+)
dis[id][xx][yy]=dis[id][x][y]+,q.push(xx*m+yy); }
}
}
int deep[maxn];
bool vis[maxn];
inline void find(){
CLR(deep,);
queue<int >q;
vis[st]=;
q.push(st);
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=head[u];i!=-;i=a[i].Next)
{
if(a[i].f && !vis[a[i].to]){
q.push(a[i].to);
deep[a[i].to]=deep[u]+;
vis[a[i].to]=;
}
}
}
}
int dfs(int u,int delta){
if(u==t)return delta;
int ret=;
for(int i=head[u];delta&&i!=-;i=a[i].Next){
if(a[i].f&&deep[a[i].to]==deep[u]+){
int dd=dfs(a[i].to,min(a[i].f,delta));
a[i].f-=dd;
a[i^].f+=dd;
delta-=dd;
ret+=dd;
}
}
return ret;
}
inline bool check(int x){
st=,t=maxn-,tot=;
CLR(head,-);
for(int i=;i<=sum;i++)addv(st,i,);
for(int k=;k<=cnt;k++)
for(int i=;i<n;i++)
for(int j=;j<m;j++)
if(s[i][j]=='.'&&dis[k][i][j]<=x)
addv(g[i][j],sum+(k-)*x+dis[k][i][j],); for (int i=; i<=cnt; i++)
for (int j=; j<=x; j++) {
int tmp=(i-)*x+sum;
addv(tmp+j,t,);
if (j<x) addv(tmp+j,tmp+j+,inf);
}
int ret=;
while(){
CLR(vis,);
find();
if(!vis[t]){
return ret==sum;
}
ret+=dfs(st,inf);
}
}
int main(){
cin>>n>>m;
for(int i=;i<n;i++)
{
scanf("%s",s[i]);
}
for(int i=;i<n;i++)
{
for(int j=;j<m;j++)
{
if(s[i][j]=='D'){
ed[++cnt]=i*m+j;
}
if(s[i][j]=='.')g[i][j]=++sum;
}
}
CLR(dis,0x3f);
for(int i=;i<=cnt;i++)
{
bfs(i);
}
int l=,r=n*m,mid;
int ans;
if(!check(r)){
puts("impossible");
return ;
}
while(l<=r){ mid=(l+r)>>;//printf("l:%d r:%d mid:%d\n",l,r,mid);
if(check(mid)){
ans=mid,r=mid-;
// printf("ans:%d\n",ans);
}
else l=mid+;
}
cout<<ans<<endl; }
1189: [HNOI2007]紧急疏散evacuate
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 3825 Solved: 1118
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
XXXXX
X...D
XX.XX
X..XX
XXDXX
Sample Output
bzoj 1189 二分+最大流的更多相关文章
- bzoj 1189 二分+最大流判定
首先我们可以二分一个答案时间T,这样就将最优性问题 转化为了判定性问题.下面我们考虑对于已知的T的判定 对于矩阵中所有的空点bfs一次,得出来每个点到门的距离, 然后连接空点和每个能在t时间内到达的门 ...
- BZOJ 1189 二分匹配 || 最大流
1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1155 Solved: 420[Submi ...
- bzoj 1305 二分+最大流判定|贪心
首先我们二分一个答案mid,在判定是否能举办mid次,那么对于每个次我们可以用最大流根据是否满流(流量为n*mid)来判定,对于每个点我们拆成两个点,分别表示这个人要和他喜欢和不喜欢的人一起跳舞,那么 ...
- uvalive 3231 Fair Share 公平分配问题 二分+最大流 右边最多流量的结点流量尽量少。
/** 题目: uvalive 3231 Fair Share 公平分配问题 链接:https://vjudge.net/problem/UVALive-3231 题意:有m个任务,n个处理器,每个任 ...
- poj 2391 Ombrophobic Bovines 最短路 二分 最大流 拆点
题目链接 题意 有\(n\)个牛棚,每个牛棚初始有\(a_i\)头牛,最后能容纳\(b_i\)头牛.有\(m\)条道路,边权为走这段路所需花费的时间.问最少需要多少时间能让所有的牛都有牛棚可待? 思路 ...
- HDU3081 Marriage Match II —— 传递闭包 + 二分图最大匹配 or 传递闭包 + 二分 + 最大流
题目链接:https://vjudge.net/problem/HDU-3081 Marriage Match II Time Limit: 2000/1000 MS (Java/Others) ...
- HDU-3081-Marriage Match II 二分图匹配+并查集 OR 二分+最大流
二分+最大流: 1 //题目大意:有编号为1~n的女生和1~n的男生配对 2 // 3 //首先输入m组,a,b表示编号为a的女生没有和编号为b的男生吵过架 4 // 5 //然后输入f组,c,d表示 ...
- hdu4560 不错的建图,二分最大流
题意: 我是歌手 Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total Subm ...
- POJ3228二分最大流
题意: 有n个点,每个点有两个权值,金子数量还有仓库容量,金子可以存在自己的仓库里或者是别的仓库里,仓库和仓库之间有距离,问所有金子都必须存到库里最大距离的最小是多少? 思路: ...
随机推荐
- linux(2)
- xgboost dmatrix中的 weight的重要性
https://stackoverflow.com/questions/35983565/how-is-the-parameter-weight-dmatrix-used-in-the-gradien ...
- Oracle sql语句执行顺序(转)
from: http://blog.csdn.net/lailai186/article/details/12612263 sql语法的分析是从右到左 一.sql语句的执行步骤:1)语法分析,分析语句 ...
- javascript总结9:JavaScript三目运算符
1 三元表达式: 表达式?结果1:结果2: 如果表达式结果为true,执行结果1,如果表达式结果为false,执行结果2. 可以理解为if else 的另外一种写法. 例: var m = 10; ...
- jsp-MySQL连接池
1.将数据库驱动程序的JAR文件放在Tomcat的 common/lib 中: mysql-connector-java-5.1.18-bin.jar 下载地址:https://yunpan.cn/c ...
- HTML5拓扑3D机房,电力工控Web SCADA
http://www.hightopo.com/cn-index.html 一套丰富的JavaScript界面类库, 提供完整的基于HTML5图形界面组件库.使用HT for Web您可以轻松构建现代 ...
- POJ2442 Sequence(堆的骚操作)
Description Given m sequences, each contains n non-negative integer. Now we may select one number fr ...
- Log--日志变大原因总结
1. 有产生大日志操作,如重建整理索引,大量数据修改等2. 长期未提交事务,为保证为提交事务可以回滚,从最早为提交事务开始之后的所有事务,都是活动事务,不能被截断或覆盖3. 日志没有定期备份4. 镜像 ...
- 平台播放声音(ext.js)
首先把需要的两个js文件放在public/core路径下 (文件已经上传到博客了) 音频文件放在文件一级目录 代码:JxCustom.loadAudio("wav/NG.wav") ...
- 转载:ResultMap和ResultType在使用中的区别
在使用mybatis进行数据库连接操作时对于SQL语句返回结果的处理通常有两种方式,一种就是resultType另一种就是resultMap,下面说下我对这两者的认识和理解 resultType:当使 ...