[HNOI 2007] 紧急疏散
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=1189
[算法]
首先 , 答案具有单调性 , 不妨二分答案” 第mid秒是否可以完成疏散 ”
检验时 , 首先通过广度优先搜索BFS求出每扇门到每个空地的距离
然后建图 , 判断最大流是否等于空地的数量
详见代码
时间复杂度: O(dinic(N ^ 3 , N ^ 3) log N ^ 2)
[代码]
#include<bits/stdc++.h>
using namespace std;
#define MAXN 16100
#define MAXD 25
const int inf = 2e9;
const int dx[] = { , , - , };
const int dy[] = {- , , , }; struct edge
{
int to , w , nxt;
} e[MAXN << ]; int tot , cntk , cntd , S , T , n , m;
int head[MAXN] , depth[MAXN];
int point[MAXD][MAXD];
int dist[MAXN][MAXD][MAXD];
char mp[MAXD][MAXD];
pair<int , int> a[MAXN * MAXD]; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
inline void addedge(int u , int v , int w)
{
++tot;
e[tot] = (edge){v , w , head[u]};
head[u] = tot;
++tot;
e[tot] = (edge){u , , head[v]};
head[v] = tot;
}
inline bool valid(int x , int y)
{
return x >= && x <= n && y >= && y <= m;
}
inline void do_bfs(int s)
{
queue< pair<int , int> > q;
q.push(make_pair(a[s].first , a[s].second));
memset(dist[s] , 0x3f , sizeof(dist[s]));
dist[s][a[s].first][a[s].second] = ;
while (!q.empty())
{
pair<int , int> cur = q.front();
q.pop();
for (int i = ; i < ; i++)
{
int nx = cur.first + dx[i] , ny = cur.second + dy[i];
if (valid(nx , ny) && mp[nx][ny] == '.')
{
if (dist[s][cur.first][cur.second] + < dist[s][nx][ny])
{
dist[s][nx][ny] = dist[s][cur.first][cur.second] + ;
q.push(make_pair(nx , ny));
}
}
}
}
}
inline bool bfs()
{
int l , r;
static int q[MAXN];
q[l = r = ] = S;
memset(depth , ,sizeof(depth));
depth[S] = ;
while (l <= r)
{
int cur = q[l++];
for (int i = head[cur]; i; i = e[i].nxt)
{
int v = e[i].to , w = e[i].w;
if (w > && !depth[v])
{
depth[v] = depth[cur] + ;
q[++r] = v;
if (v == T) return true;
}
}
}
return false;
}
inline int dinic(int u , int flow)
{
int rest = flow , ret = ;
if (u == T) return flow;
for (int i = head[u]; i && rest; i = e[i].nxt)
{
int v = e[i].to , w = e[i].w;
if (depth[v] == depth[u] + && w)
{
int k = dinic(v , min(rest , w));
if (!k) depth[v] = ;
e[i].w -= k;
e[i ^ ].w += k;
rest -= k;
}
}
return flow - rest;
}
inline bool check(int mid)
{
S = cntk + cntd * mid + cntd + ;
T = S + ;
tot = ;
for (int i = ; i <= T; i++) head[i] = ;
for (int i = ; i <= n; i++)
{
for (int j = ; j <= m; j++)
{
if (mp[i][j] == '.')
addedge(S , point[i][j] , );
}
}
for (int i = ; i <= cntd; i++)
{
for (int j = ; j <= n; j++)
{
for (int k = ; k <= m; k++)
{
if (mp[j][k] == '.' && dist[i][j][k] <= mid)
addedge(point[j][k] , cntk + (i - ) * mid + dist[i][j][k] , );
}
}
}
for (int i = ; i <= cntd; i++)
{
for (int j = ; j <= mid; j++)
{
addedge(cntk + (i - ) * mid + j , cntk + cntd * mid + i , mid - j + );
}
}
for (int i = ; i <= cntd; i++) addedge(cntk + cntd * mid + i , T , mid);
int ret = ;
while (bfs())
{
while (int flow = dinic(S , inf)) ret += flow;
}
return ret == cntk;
} int main()
{ scanf("%d%d" , &n , &m);
for (int i = ; i <= n; i++) scanf("%s" , mp[i] + );
for (int i = ; i <= n; i++)
{
for (int j = ; j <= m; j++)
{
if (mp[i][j] == '.')
point[i][j] = ++cntk;
if (mp[i][j] == 'D') a[++cntd] = make_pair(i , j);
}
}
for (int i = ; i <= cntd; i++) do_bfs(i);
int l = , r = n * m , ans = -;
while (l <= r)
{
int mid = (l + r) >> ;
if (check(mid))
{
ans = mid;
r = mid - ;
} else l = mid + ;
}
if (ans >= ) printf("%d\n" , ans);
else printf("impossible\n"); return ; }
[HNOI 2007] 紧急疏散的更多相关文章
- 博弈论(SG函数):HNOI 2007 分裂游戏
Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏. 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子 ...
- Solution -「HNOI 2007」「洛谷 P3185」分裂游戏
\(\mathcal{Description}\) Link. 给定 \(n\) 堆石子,数量为 \(\{a_n\}\),双人博弈,每轮操作选定 \(i<j\le k\),使 \(a_i ...
- [插头DP自我总结]
[HNOI 2007]神奇游乐园 #include <bits/stdc++.h> #define maxn 110 using namespace std; typedef long l ...
- [HNOI2007]紧急疏散EVACUATE (湖南2007年省选)
[HNOI2007]紧急疏散EVACUATE 题目描述 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一块空地:如果是'X',那么表示这是一面 ...
- poi读取excel模板,填充内容并导出,支持导出2007支持公式自动计算
/** * 版权所有(C) 2016 * @author www.xiongge.club * @date 2016-12-7 上午10:03:29 */ package xlsx; /** * @C ...
- BZOJ 2007: [Noi2010]海拔
2007: [Noi2010]海拔 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2410 Solved: 1142[Submit][Status] ...
- 开源WinForms界面开发框架Management Studio 选项卡文档 插件 Office 2007蓝色风格 后台线程
Management Studio是我在WinForms小项目开发过程中搭建起来的一个插件式结构的应用程序框架,因为简单灵活又容易扩展,现在将它开源供读者参考. 跑起来的效果图如下所示,具备选项卡式多 ...
- win7下wndows virtual pc 2007 装xp比新版本的 Windows virtual pc 好用
2007下装xp虚拟机启动快,支持拖放.
- [SharePoint 2007/2010]Query SharePoint Calendar Event
首先要搞清楚日历事件的各种类型,参考文章: http://sharepoint.microsoft.com/blog/Pages/BlogPost.aspx?PageType=4&ListId ...
随机推荐
- HDU-2647 Reward ,逆拓排。
Reward 发工资,以前看过这题,做没做忘了(应该是没做). 很明显的拓排.但数据范围这么大,吓得我当时就不敢动手.后来找题解发现还是相当于两层循环(are you kidding me?)当时卡在 ...
- PTA 04-树4 是否同一棵二叉搜索树 (25分)
题目地址 https://pta.patest.cn/pta/test/15/exam/4/question/712 5-4 是否同一棵二叉搜索树 (25分) 给定一个插入序列就可以唯一确定一棵二 ...
- Linux(5):正则表达式 & 权限
正则表达式: 特殊符号: '' ---> 所见即所得,里面的内容都会被原封不动的输出出来 "" ---> 与单引号类似,但其中的特殊符号会被解析运行 `` ---> ...
- 权限对于目录和文件的具体含义 linux
权限对于具体文件的含义 文件上存储具体数据的地方,包括一般文件,数据库文件,二进制可执行文件等.因此权限对于文件的意义上这样都 r: 可读权限,表示可以读取该文件的内容 w:可写权限,表示可以编辑,新 ...
- makefile的语法及写法(二)
3 Makefile书写规则 -------------------------------------------------------------------------------- 规则包 ...
- 从CLR GC到CoreCLR GC看.NET Core对云原生的支持
内存分配概要 前段时间在园子里看到有人提到了GC学习的重要性,很赞同他的观点.充分了解GC可以帮助我们更好的认识.NET的设计以及为何在云原生开发中.NET Core会占有更大的优势,这也是一个程序员 ...
- Meteor结构
Meteor提供了一些特殊的文件夹,可以帮助开发人员构建他们的应用程序. client 如果创建客户端文件夹,这个文件夹里面的一切都将在客户端上运行.在这里,可以将您的HTML,CSS和客户端Java ...
- django 简易博客开发 3 静态文件、from 应用与自定义
首先还是贴一下源代码地址 https://github.com/goodspeedcheng/sblog 上一篇博客我们介绍了 django 如何在views中使用templates以及一些常用的数 ...
- Centos 6.x 安装Nagios及WEB管理nagiosql实现windows及linux监控指南
一.Nagios简介 Nagios是一款开源的电脑系统和网络监视工具,能有效监控Windows.Linux和Unix的主机状态,交换机路由器等网络设置,打印机等.在系统或服务状态异常时发出邮件或短信报 ...
- UVALive3211- Now or later(二分+2-SAT)
题目链接 题意:有n架飞机.每架飞机都能够选择早着陆和晚着陆两种方式之中的一个,且必须选择一种. 任务就是安排全部飞机着陆时.相邻两个着陆时间间隔的最小值尽量大. 思路:用二分处理最小值尽量大.该题目 ...