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个点,每个点有两个权值,金子数量还有仓库容量,金子可以存在自己的仓库里或者是别的仓库里,仓库和仓库之间有距离,问所有金子都必须存到库里最大距离的最小是多少? 思路: ...
随机推荐
- JS中的两种刷新方法以及区别和适用范围
在项目中有一个人信息修改的页面,但是修改后显示的却是修改之前的内容,分析问题后发现查询语句写在了修改语句之前,有些某些需要又必须这么写,但是修改信息后先却显示之前的信息也太不科学了. 所以我就想用js ...
- 345. Reverse Vowels of a String翻转字符串中的元音字母
[抄题]: Write a function that takes a string as input and reverse only the vowels of a string. Example ...
- 2.Books
Books示例说明了Qt中SQL类如何被Model/View框架使用,使用数据库中存储的信息,创建丰富的用户界面. 首先介绍使用SQL我们需要了解的类: 1.QSqlDatabase: QSqlDat ...
- [GO]二维数组的介绍
package main import "fmt" func main() { ][]int // 有几个方括号就是几维数据 // 有几个方括号就需要几重循环 k := ; i&l ...
- (字符串)ZigZag Conversion
[解析] 第一次看到这个题目的人,可能不知道ZigZag是什么意思,简单解释一下,就是把字符串原顺序012345……按下图所示排列: 发现所有行的重复周期都是 2 * nRows - 2 对于首行和末 ...
- System.Web.UI.Page事件执行顺序
#region OnPreInit 第一步(显式重写,文章下面有隐式重写) protected override void OnPreInit(EventArgs e) { //检查 IsPostBa ...
- 【Head First Java 读书笔记】(四)对象的行为
状态影响行为,行为影响状态 对象有状态和行为 类所描述的是对象知道什么和执行什么. 同一类型的每个对象能够有不同的方法行为吗? 任一类的每个实例都带有相同的方法,但是方法可以根据实例变量的值来表现不同 ...
- 拉登是我罩的队_第三周_需求改进&原型设计
需求改进&原型设计 1. 需求&原型改进 1.1硬件部分(1) 硬件部分分为主机和遥控器,分别由两个单片机进行控制.(2) 单片机1:负责显示游戏的界面.使用数码管显示当前得分,使用不 ...
- DELPHI XE5 UP2 运行IOS 遇到 Wrapper init failed: (null)问题的解决办法
一.问题表现: 在MAC OSX(10.9.2)上安装了比较新的XCODE5.1 和COMMAND LINE TOOLS 在DELPHI XE5 UP2上放了一个按钮,输出到MAC OSX上,出现: ...
- 人力资源管理 winform C#
主旨思想:数据库(增,删,改,查) 资源管理器目的:实现基本人员信息 存储,调用,查看头像,修改内容. 注意事项: 1.建立两个表格 (人员表(cold,name,bumen,phone,t ...