【法一】枚举Time(0~N*M):

S->'.'(1);

'D'->T(Time);

'.'->'D'(dis(用BFS预处理,注意一旦到达'D',BFS就不能继续扩展了,注意dis的初值0x7f)<=Time ? 1 : 0);

判断是否满流;

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define INF 2147483647
#define MAXN 411
#define MAXM 350001
int v[MAXM],cap[MAXM],en,first[MAXN],next[MAXM];
int d[MAXN],cur[MAXN];
queue<int>q;
int n,S,T,N,M;
void Init_Dinic(){memset(first,-1,sizeof(first)); en=0; S=0; n=N*M+2; T=N*M+1;}
void AddEdge(const int &U,const int &V,const int &W)
{v[en]=V; cap[en]=W; next[en]=first[U]; first[U]=en++;
v[en]=U; next[en]=first[V]; first[V]=en++;}
bool bfs()
{memset(d,-1,sizeof(d)); q.push(S); d[S]=0;while(!q.empty()){int U=q.front(); q.pop();for(int i=first[U];i!=-1;i=next[i])if(d[v[i]]==-1 && cap[i]){d[v[i]]=d[U]+1;q.push(v[i]);}}return d[T]!=-1;
}
int dfs(int U,int a)
{if(U==T || !a) return a;int Flow=0,f;for(int &i=cur[U];i!=-1;i=next[i])if(d[U]+1==d[v[i]] && (f=dfs(v[i],min(a,cap[i])))){cap[i]-=f; cap[i^1]+=f;Flow+=f; a-=f; if(!a) break;}if(!Flow) d[U]=-1;return Flow;
}
int max_flow()
{int Flow=0,tmp=0;while(bfs()){memcpy(cur,first,(n+5)*sizeof(int));while(tmp=dfs(S,INF)) Flow+=tmp;}return Flow;
}
int dis[22*22][22*22];
bool vis[22][22];
char map[22][22];
int num[22][22];
struct Node
{int x,y,d;Node(const int &a,const int &b,const int &c){x=a;y=b;d=c;}Node(){}
};
const int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
int man[22*22],door[22*22],summ,sumd;
int main()
{scanf("%d%d",&N,&M);for(int i=1;i<=N;++i) scanf("%s",map[i]+1);for(int i=1;i<=N;++i)for(int j=1;j<=M;++j){num[i][j]=++en;if(map[i][j]=='.') man[++summ]=en;else if(map[i][j]=='D') door[++sumd]=en;}memset(dis,0x7f,sizeof(dis));queue<Node>q;for(int i=1;i<=N;++i)for(int j=1;j<=M;++j)if(map[i][j]=='.'){memset(vis,0,sizeof(vis));q.push(Node(i,j,0));vis[i][j]=1;while(!q.empty()){Node U=q.front(); q.pop();for(int k=0;k<4;++k){int tx=U.x+dx[k],ty=U.y+dy[k];if(tx>=1 && tx<=N && ty>=1 && ty<=M && map[tx][ty]!='X' && (!vis[tx][ty])){if(map[tx][ty]=='D'){dis[num[i][j]][num[tx][ty]]=U.d+1;continue;//注意:到了门立刻离开,不能继续。 }vis[tx][ty]=1;q.push(Node(tx,ty,U.d+1));}}}}for(int Time=0;Time<=N*M;++Time){Init_Dinic();for(int i=1;i<=summ;++i) AddEdge(S,man[i],1);for(int i=1;i<=sumd;++i) AddEdge(door[i],T,Time);for(int i=1;i<=summ;++i)for(int j=1;j<=sumd;++j)if(dis[man[i]][door[j]]<=Time)AddEdge(man[i],door[j],1);if(max_flow()==summ){printf("%d\n",Time);return 0;}}puts("impossible");return 0;
}

  

【法二】可以二分答案,但是边界总是挂……分块答案。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
#define INF 2147483647
#define MAXN 411
#define MAXM 350001
int v[MAXM],cap[MAXM],en,first[MAXN],next[MAXM];
int d[MAXN],cur[MAXN];
queue<int>q;
int n,S,T,N,M;
void Init_Dinic(){memset(first,-1,sizeof(first)); en=0; S=0; n=N*M+2; T=N*M+1;}
void AddEdge(const int &U,const int &V,const int &W)
{v[en]=V; cap[en]=W; next[en]=first[U]; first[U]=en++;
v[en]=U; next[en]=first[V]; first[V]=en++;}
bool bfs()
{memset(d,-1,sizeof(d)); q.push(S); d[S]=0;while(!q.empty()){int U=q.front(); q.pop();for(int i=first[U];i!=-1;i=next[i])if(d[v[i]]==-1 && cap[i]){d[v[i]]=d[U]+1;q.push(v[i]);}}return d[T]!=-1;
}
int dfs(int U,int a)
{if(U==T || !a) return a;int Flow=0,f;for(int &i=cur[U];i!=-1;i=next[i])if(d[U]+1==d[v[i]] && (f=dfs(v[i],min(a,cap[i])))){cap[i]-=f; cap[i^1]+=f;Flow+=f; a-=f; if(!a) break;}if(!Flow) d[U]=-1;return Flow;
}
int max_flow()
{int Flow=0,tmp=0;while(bfs()){memcpy(cur,first,(n+5)*sizeof(int));while(tmp=dfs(S,INF)) Flow+=tmp;}return Flow;
}
int dis[22*22][22*22];
bool vis[22][22];
char map[22][22];
int num[22][22];
struct Node
{int x,y,d;Node(const int &a,const int &b,const int &c){x=a;y=b;d=c;}Node(){}
};
const int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
int man[22*22],door[22*22],summ,sumd;
void Rebuild(const int &Time)
{Init_Dinic();for(int i=1;i<=summ;++i) AddEdge(S,man[i],1);for(int i=1;i<=sumd;++i) AddEdge(door[i],T,Time);for(int i=1;i<=summ;++i)for(int j=1;j<=sumd;++j)if(dis[man[i]][door[j]]<=Time)AddEdge(man[i],door[j],1);
}
int main()
{scanf("%d%d",&N,&M);for(int i=1;i<=N;++i) scanf("%s",map[i]+1);for(int i=1;i<=N;++i)for(int j=1;j<=M;++j){num[i][j]=++en;if(map[i][j]=='.') man[++summ]=en;else if(map[i][j]=='D') door[++sumd]=en;}memset(dis,0x7f,sizeof(dis));queue<Node>q;for(int i=1;i<=N;++i)for(int j=1;j<=M;++j)if(map[i][j]=='.'){memset(vis,0,sizeof(vis));q.push(Node(i,j,0));vis[i][j]=1;while(!q.empty()){Node U=q.front(); q.pop();for(int k=0;k<4;++k){int tx=U.x+dx[k],ty=U.y+dy[k];if(tx>=1 && tx<=N && ty>=1 && ty<=M && map[tx][ty]!='X' && (!vis[tx][ty])){if(map[tx][ty]=='D'){dis[num[i][j]][num[tx][ty]]=U.d+1;continue;//注意:到了门立刻离开,不能继续。 }vis[tx][ty]=1;q.push(Node(tx,ty,U.d+1));}}}}int sz=sqrt(N*M),last=0;for(int Time=0;last<=N*M;Time+=sz){Rebuild(Time);if(max_flow()>=summ){for(int i=last+1;i<=Time;++i){Rebuild(i);if(max_flow()==summ){printf("%d\n",i); return 0;}}return 0;} last=Time;}puts("impossible");return 0;
}

  

转载于:https://www.cnblogs.com/autsky-jadek/p/4175085.html

【枚举】【二分答案】【分块答案】【BFS】【最大流】【Dinic】bzoj1189 [HNOI2007]紧急疏散evacuate...相关推荐

  1. bzoj1189 [HNOI2007]紧急疏散evacuate(二分答案+bfs+最大流判是否满流)

    首先bfs处理出每个人到每个门所需的时间.然后二分答案,对于所有人能到的所有门,建边,边权为1,从源点向所有人建边,边权为1,从所有门向汇点建边,边权为mid(最多出去mid个人),dinic跑最大流 ...

  2. bzoj1189 [HNOI2007]紧急疏散EVACUATE spfa+网络流+二分

    这个题是非常暴力的匹配问题. 首先最好想的思路是给每个人分门的决策, 每个人到每个门的距离直接暴力最短路即可 但不能算出一个门被多个人经过的情况 所以就有了暴力的想法,再给每个人.对每一个门分配一个时 ...

  3. 【分块答案】【最小割】bzoj1532 [POI2005]Kos-Dicing

    引用zky的题解:http://blog.csdn.net/iamzky/article/details/39667859 每条S-T路径代表一次比赛的结果.最小割会尽量让一个人赢得最多. 因为二分总 ...

  4. 秒速五厘米(快速二分跳跃查找答案)

    秒速五厘米(快速二分跳跃查找答案) **秒速五厘米(快速二分跳跃查找答案) 让我们来看这道题(题目来源:吉首大学) #问题 D: 秒速五厘米 描述 樱花飘落的速度,每秒五厘米. 动漫<秒速五厘米 ...

  5. 【HDU 5936 --- Difference】折半枚举+二分

    [HDU 5936 --- Difference]折半枚举+二分 Description Little Ruins is playing a number game, first he chooses ...

  6. python程序设计基础第三版_Python程序设计基础_知到免费答案全套答案

    Python程序设计基础_知到免费答案全套答案 答案: 更多相关问题 动滑轮牵引提升工作说法错误的是()A.省功B.省力C.速度快D.不省功 填写隔离开关检修记录时应清晰明了,语言简炼,内容主要包括( ...

  7. python只能以程序方式执行死刑_Python程序设计基础_2020智慧树网课答案章节答案...

    Python程序设计基础_2020智慧树网课答案章节答案 答案: 更多相关问题 审判时怀孕的妇女,无论犯了多么严重的罪,最高可以判处().A.死刑立即执行B.无期徒刑C.有期徒刑 甲见他人贩卖毒品获得 ...

  8. 软件测试方法与技术第三版课后答案完整版,软件测试方法与技术朱少民第三章答案部分答案.docx...

    软件测试方法与技术朱少民第三章答案部分答案 3.综合应用边界值和等价类划分方法设计相应的测试用例,包括尽可能多的无效等价类:输入三个参数作为边,分别满足一般三角形,等腰三角形和等边三角形.答:边边边输 ...

  9. 洛谷 P2053 [SCOI2007]修车 网络流 最小费用最大流 Dinic+Spfa

    题目链接: https://www.luogu.com.cn/problem/P2053 思路参考博客: https://www.luogu.com.cn/blog/a23333/solution-p ...

最新文章

  1. Hadoop概念学习系列之为什么hadoop/spark执行作业时,输出路径必须要不存在?(三十九)...
  2. OTS parsing error: invalid version tag woff和ttf文件被Filter拦截
  3. 33%制造企业跑步上云,云MES市场将达到23.4亿美元
  4. 网页设计作业_Dreamweaver简单网页成品
  5. 六十四、SpringBoot中的模板引擎Thymeleaf
  6. 数据库-数据库的常用术语
  7. 159.majority element
  8. python 笔记 冒泡排序
  9. 大数据概述(尚硅谷)
  10. Oracle中SQL*plus常用命令
  11. dll中封装MFC(VC2012)资源--自定义一个复用的登录界面
  12. 【从零开始的OpenGL学习】1. 配置OpenGL,绘制最简单的一个三角形,HelloWorld(学习笔记)
  13. Java实现阿拉伯数字转换成汉字数字
  14. matlab t tide,[转载]t_tide潮汐潮流调和分析工具包教程
  15. 华为服务器ip从bios哪里修改,服务器bios设置ip
  16. 苹果电脑与xcode的快捷键
  17. 西门子三菱台达PLC读取国网DLT645协议电表数据方案
  18. 数据库笔记——Mysql、Oracle、Sqlserver || Redis、Memcached、mongoDB环境搭建
  19. writeup-woo
  20. 【考研】2022暨南大学848 电子信息(计算机技术) 经验贴 经验贴汇总

热门文章

  1. 一文读懂你该了解的5G知识:现在别买5G手机
  2. 哈萨比斯导师:人工智能媲美人类或需两百年,神经学是条出路
  3. MIT联合波士顿咨询:全球21个行业,对话3000名高管,AI如何重塑商业形态? | 雷报
  4. 【Java】 Java网络编程总结
  5. ubuntu 设置root用户密码并实现root用户登录
  6. springcloud搭建篇
  7. 自己封装的一个java图片验证码
  8. 禁止蒙层底部页面跟随滚动 1
  9. 爱立信前CEO Hans Vestberg成为Verizon三巨头之一
  10. Mac 装Sequel pro 连接 Mysql 8.0 失败、登录不了、loading问题