题目大概说一个n×m的格子中,'.'代表空地,'#'代表障碍,'K'代表骑士,'D'代表目的地。骑士每走一步花一条,每一步可以往(+2,+3)(-2,+3)...八个方向走,问占领所有目的地最少要几天。

二分枚举天数用最大流判定能否成立——建图关键在于把每一个格子点拆成天数个的点,因为每个格子每天只能容纳一个骑士所以各个天的点再拆成两个点之间连容量1的边,然后就是对所有第i天的点向所有第i+1天的点连容量1的边。

 #include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define INF (1<<30)
#define MAXN 66666
#define MAXM 888888
struct Edge{
int v,cap,flow,next;
}edge[MAXM];
int vs,vt,NV,NE,head[MAXN];
void addEdge(int u,int v,int cap){
edge[NE].v=v; edge[NE].cap=cap; edge[NE].flow=;
edge[NE].next=head[u]; head[u]=NE++;
edge[NE].v=u; edge[NE].cap=; edge[NE].flow=;
edge[NE].next=head[v]; head[v]=NE++;
}
int level[MAXN];
int gap[MAXN];
void bfs(){
memset(level,-,sizeof(level));
memset(gap,,sizeof(gap));
level[vt]=;
gap[level[vt]]++;
queue<int> que;
que.push(vt);
while(!que.empty()){
int u=que.front(); que.pop();
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(level[v]!=-) continue;
level[v]=level[u]+;
gap[level[v]]++;
que.push(v);
}
}
}
int pre[MAXN];
int cur[MAXN];
int ISAP(){
bfs();
memset(pre,-,sizeof(pre));
memcpy(cur,head,sizeof(head));
int u=pre[vs]=vs,flow=,aug=INF;
gap[]=NV;
while(level[vs]<NV){
bool flag=false;
for(int &i=cur[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[u]==level[v]+){
flag=true;
pre[v]=u;
u=v;
aug=min(aug,edge[i].cap-edge[i].flow);
if(v==vt){
flow+=aug;
for(u=pre[v]; v!=vs; v=u,u=pre[u]){
edge[cur[u]].flow+=aug;
edge[cur[u]^].flow-=aug;
}
aug=INF;
}
break;
}
}
if(flag) continue;
int minlevel=NV;
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[v]<minlevel){
minlevel=level[v];
cur[u]=i;
}
}
if(--gap[level[u]]==) break;
level[u]=minlevel+;
gap[level[u]]++;
u=pre[u];
}
return flow;
}
int dx[]={,,-,-,,-,,-};
int dy[]={,-,,-,,,-,-};
char map[][];
int n,m,tot;
bool isok(int day){
vs=***; vt=vs+; NV=vt+; NE=;
memset(head,-,sizeof(head));
for(int i=; i<n; ++i){
for(int j=; j<m; ++j){
if(map[i][j]=='#') continue;
if(map[i][j]=='K') addEdge(vs,i*m+j,);
else if(map[i][j]=='D') addEdge(i*m+j+n*m*day+,vt,);
for(int t=; t<=day; ++t){
addEdge(i*m+j+n*m*t,i*m+j+n*m*t+,);
if(t==day) continue;
addEdge(i*m+j+n*m*t+,i*m+j+n*m*(t+),);
for(int k=; k<; ++k){
int nx=i+dx[k],ny=j+dy[k];
if(nx< || nx>=n || ny< || ny>=m || map[nx][ny]=='#') continue;
addEdge(i*m+j+n*m*t+,nx*m+ny+n*m*(t+),);
}
}
}
}
return ISAP()==tot;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
tot=;
scanf("%d%d",&n,&m);
for(int i=; i<n; ++i){
for(int j=; j<m; ++j){
scanf(" %c",&map[i][j]);
if(map[i][j]=='D') ++tot;
}
}
if(tot==){
puts("");
continue;
}
int l=,r=;
while(l<r){
int mid=l+r>>;
if(isok(mid)) r=mid;
else l=mid+;
}
if(l>) puts(">30");
else printf("%d\n",l);
}
return ;
}

SCU3312 Stockholm Knights(最大流)的更多相关文章

  1. Soj题目分类

    -----------------------------最优化问题------------------------------------- ----------------------常规动态规划 ...

  2. [SPOJ962]Intergalactic Map 拆点+最大流

    Jedi knights, Qui-Gon Jinn and his young apprentice Obi-Wan Kenobi, are entrusted by Queen Padmé Ami ...

  3. SPOJ IM - Intergalactic Map - [拆点最大流]

    题目链接:http://www.spoj.com/problems/IM/en/ Time limit:491 ms Memory limit:1572864 kB Code length Limit ...

  4. SPOJ 962 Intergalactic Map (网络最大流)

    http://www.spoj.com/problems/IM/ 962. Intergalactic Map Problem code: IM Jedi knights, Qui-Gon Jinn ...

  5. 使用C#处理基于比特流的数据

    使用C#处理基于比特流的数据 0x00 起因 最近需要处理一些基于比特流的数据,计算机处理数据一般都是以byte(8bit)为单位的,使用BinaryReader读取的数据也是如此,即使读取bool型 ...

  6. HTML 事件(三) 事件流与事件委托

    本篇主要介绍HTML DOM中的事件流和事件委托. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流与事件委托 4 ...

  7. FILE文件流的中fopen、fread、fseek、fclose的使用

    FILE文件流用于对文件的快速操作,主要的操作函数有fopen.fseek.fread.fclose,在对文件结构比较清楚时使用这几个函数会比较快捷的得到文件中具体位置的数据,提取对我们有用的信息,满 ...

  8. java.IO输入输出流:过滤流:buffer流和data流

    java.io使用了适配器模式装饰模式等设计模式来解决字符流的套接和输入输出问题. 字节流只能一次处理一个字节,为了更方便的操作数据,便加入了套接流. 问题引入:缓冲流为什么比普通的文件字节流效率高? ...

  9. java 字节流与字符流的区别

    字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢?实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作 ...

随机推荐

  1. cocos基础教程(13)使用Physicals代替Box2D和chipmunk

    1.   概述 游戏中模拟真实的世界是个比较麻烦的事情,通常这种事情都是交给物理引擎来做.首屈一指的是Box2D了,它几乎能模拟所有的物理效果.而chipmunk则是个更轻量的引擎,能够满足简单的物理 ...

  2. win10 x64下安装oracle 12c出现[INS-30131]报错的解决方案

    解决方案: 第一步:控制面板>所有控制面板项>管理工具>服务>SERVER 启动 第二步:控制面板>所有控制面板项>管理工具>计算机管理>系统工具> ...

  3. Centos 7 安装LAMP环境

    一.安装Centos 官网下载Centos 7刻录成光盘后安装 二.安装apache yum install httpd #根据提示,输入Y安装即可成功安装 systemctl start httpd ...

  4. 使用nginx的proxy_cache做网站缓存

    为什么要做web cache,我想大家最主要的是解决流量的压力.随着网站流量的提升,如果只是单台机器既处理静态文件,又处理动态脚本,显然效率很难上升,不能处理日益上涨的流量压力.与此同时某些网站的页面 ...

  5. 【Spring】Spring系列1之Spring概述

    概述

  6. A + B Problem

    Write a function that add two numbers A and B. You should not use + or any arithmetic operators. 分析: ...

  7. sqlcmd

    使用sqlcmd可以在批处理脚本中执行SQL.虽然这个命令的参数很多,但幸运的是,我们不需要全部理解,在这里简要介绍以下几个: { -U login_id [ -P password ] } | –E ...

  8. 告别div,可以代替div的几个标签

    几个最常用的用来代替DIV的HTML5元素 虽说html5中大多数功能性的元素如<video><canvas><audio>等还得不到当前主流浏览器的支持(主要就是 ...

  9. 解决iphone5,5s有锁版(AU,SB,S版等等)ios7越狱后+86、FT、IM等一切问题

    最近无聊,给大家发一个关于完美解决iphone5,5c.5s有锁版本机号码.+86.短信.facetime.imessage等问题.是ios7系统哦!(本人亲测iphone5 SB版 双模卡解锁)相当 ...

  10. linux编译中的常见问题

    转linux编译中的常见问题 错误提示:Makefile:2: *** 遗漏分隔符 . 停止. 原因makefile中 gcc语句前 缺少一个 tab分割符 错误提示: bash: ./makefil ...