hdu 2732 最大流 **
题意:题目是说一个n*m的迷宫中,有每个格子有柱子。柱子高度为0~3,高度为0的柱子是不能站的(高度为0就是没有柱子)在一些有柱子的格子上有一些蜥蜴,一次最多跳距离d,相邻格子的距离是1,只要跳出迷宫就是安全的。这个距离是曼哈顿距离(好像是的)。蜥蜴一次最多跳距离d,但是起跳的地方的柱子高度会减一,一个柱子同一时间只能有一个蜥蜴要求最少几个不能逃出迷宫。
链接:点我
看懂了,明天拍
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
#define MOD 1000000007
#define pb(a) push_back(a)
const int INF=0x3f3f3f3f;
const double eps=1e-;
typedef long long ll;
#define cl(a) memset(a,0,sizeof(a))
#define ts printf("*****\n");
const int MAXN=;
int n,m,tt,cnt;
char s1[][],s2[][];
struct Edge
{
int to,next,cap,flow;
}edge[];//注意是MAXM
int tol;
int head[MAXN];
int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];
int maze[][];
void init()
{
tol = ;
memset(head,-,sizeof(head));
}
//加边,单向图三个参数,双向图四个参数
void addedge(int u,int v,int w,int rw=)
{
edge[tol].to = v;edge[tol].cap = w;edge[tol].next = head[u];
edge[tol].flow = ;head[u] = tol++;
edge[tol].to = u;edge[tol].cap = rw;edge[tol].next = head[v];
edge[tol].flow = ;head[v]=tol++;
}
//输入参数:起点、终点、点的总数
//点的编号没有影响,只要输入点的总数
int sap(int start,int end,int N)
{
memset(gap,,sizeof(gap));
memset(dep,,sizeof(dep));
memcpy(cur,head,sizeof(head));
int u = start;
pre[u] = -;
gap[] = N;
int ans = ;
while(dep[start] < N)
{
if(u == end)
{
int Min = INF;
for(int i = pre[u];i != -; i = pre[edge[i^].to])
if(Min > edge[i].cap - edge[i].flow)
Min = edge[i].cap - edge[i].flow;
for(int i = pre[u];i != -; i = pre[edge[i^].to])
{
edge[i].flow += Min;
edge[i^].flow -= Min;
}
u = start;
ans += Min;
continue;
}
bool flag = false;
int v;
for(int i = cur[u]; i != -;i = edge[i].next)
{
v = edge[i].to;
if(edge[i].cap - edge[i].flow && dep[v]+ == dep[u])
{
flag = true;
cur[u] = pre[v] = i;
break;
}
}
if(flag)
{
u = v;
continue;
}
int Min = N;
for(int i = head[u]; i != -;i = edge[i].next)
if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)
{
Min = dep[edge[i].to];
cur[u] = i;
}
gap[dep[u]]--;
if(!gap[dep[u]])return ans;
dep[u] = Min+;
gap[dep[u]]++;
if(u != start) u = edge[pre[u]^].to;
}
return ans;
}
int main()
{
int i,j,k;
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
#endif
scanf("%d",&tt);
int ca=;
int d;
while(tt--)
{
ca++;
init();
scanf("%d%d",&n,&d);
for(i=;i<n;i++)
{
scanf("%s",&s1[i]);
}
m=strlen(s1[]);
int tot=;
cl(maze);
for(i=;i<n;i++)
{
for(j=;j<m;j++)
{
if(s1[i][j]>'') //说明改点可跳
{
maze[i][j]=++tot;
addedge(*tot-,*tot,s1[i][j]-'');
}
}
} //这里的tot要注意,如果一开始是tot++,那么比实际会多出一个点
int start=,end=*tot+,nodenum=*tot+;
int sum=;
for(i=;i<n;i++)
{
scanf("%s",s2[i]);
for(j=;j<m;j++)
{
if(s2[i][j]=='L')
{
sum++;
addedge(start,*maze[i][j]-,);
}
}
}
for(i=;i<n;i++)
{
for(j=;j<m;j++)
{
if(maze[i][j]) //能直接跳出边界的点连上汇点
{
for(int x=-d;x<=d;x++)
{
for(int y=fabs(x)-d;y<=d-fabs(x);y++) //新技能get
{
int ni=i+x;
int nj=j+y;
if(ni<||ni>=n||nj<||nj>=m)continue;
if(ni==i&&nj==j) continue;
if(maze[ni][nj]==) continue;
addedge(*maze[i][j],*maze[ni][nj]-,INF); //这里的跳跃是无限流的
}
}
if(i<d||j<d||n-i<=d||m-j<=d) addedge(*maze[i][j],end,INF);
}
}
}
int ans=sum-sap(start,end,nodenum);
if(ans==)printf("Case #%d: no lizard was left behind.\n",ca);
else if(ans==)printf("Case #%d: 1 lizard was left behind.\n",ca);
else printf("Case #%d: %d lizards were left behind.\n",ca,ans);
}
}
//============================================================================
// Name : HDU.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================ #include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
using namespace std; const int MAXN=;
const int MAXM=;
const int INF=0x3f3f3f3f;
struct Node
{
int to,next,cap;
}edge[MAXM];//注意是MAXM
int tol;
int head[MAXN];
int gap[MAXN],dis[MAXN],pre[MAXN],cur[MAXN]; void init()
{
tol=;
memset(head,-,sizeof(head));
}
void addedge(int u,int v,int w,int rw=)
{
edge[tol].to=v;edge[tol].cap=w;edge[tol].next=head[u];head[u]=tol++;
edge[tol].to=u;edge[tol].cap=rw;edge[tol].next=head[v];head[v]=tol++;
}
int sap(int start,int end,int nodenum)
{
memset(dis,,sizeof(dis));
memset(gap,,sizeof(gap));
memcpy(cur,head,sizeof(head));
int u=pre[start]=start,maxflow=,aug=-;
gap[]=nodenum;
while(dis[start]<nodenum)
{
loop:
for(int &i=cur[u];i!=-;i=edge[i].next)
{
int v=edge[i].to;
if(edge[i].cap&&dis[u]==dis[v]+)
{
if(aug==-||aug>edge[i].cap)
aug=edge[i].cap;
pre[v]=u;
u=v;
if(v==end)
{
maxflow+=aug;
for(u=pre[u];v!=start;v=u,u=pre[u])
{
edge[cur[u]].cap-=aug;
edge[cur[u]^].cap+=aug;
}
aug=-;
}
goto loop;
}
}
int mindis=nodenum;
for(int i=head[u];i!=-;i=edge[i].next)
{
int v=edge[i].to;
if(edge[i].cap&&mindis>dis[v])
{
cur[u]=i;
mindis=dis[v];
}
}
if((--gap[dis[u]])==)break;
gap[dis[u]=mindis+]++;
u=pre[u];
}
return maxflow;
} char g1[][];
char g2[][];
int mat[][]; int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
int n,d;
int iCase=;
scanf("%d",&T);
while(T--)
{
iCase++;
scanf("%d%d",&n,&d);
init();
int tol=;
for(int i=;i<n;i++)
scanf("%s",&g1[i]);
int m=strlen(g1[]);
memset(mat,,sizeof(mat));
for(int i=;i<n;i++)
for(int j=;j<m;j++)
if(g1[i][j]>'')
{
mat[i][j]=++tol;
addedge(*tol-,*tol,g1[i][j]-'');
} int start=,end=*tol+,nodenum=*tol+;
//进行拆点,加上源点和汇点,共2*tol+2个点。
int sum=;//总数
for(int i=;i<n;i++)
{
scanf("%s",&g2[i]);
for(int j=;j<m;j++)
if(g2[i][j]=='L')
{
sum++;
addedge(start,*mat[i][j]-,);
}
}
for(int i=;i<n;i++)
for(int j=;j<m;j++)
if(mat[i][j])
{
for(int x=-d;x<=d;x++)
for(int y=abs(x)-d;y<=d-abs(x);y++)
{
int newi=i+x;
int newj=j+y;
if(newi<||newi>=n||newj<||newj>=m)continue;
if(mat[newi][newj]==)continue;
if(newi==i&&newj==j)continue;
addedge(*mat[i][j],*mat[newi][newj]-,INF);
}
if(i<d||j<d||n-i<=d||m-j<=d)
addedge(*mat[i][j],end,INF);
}
int ans=sum-sap(start,end,nodenum);
if(ans==)printf("Case #%d: no lizard was left behind.\n",iCase);
else if(ans==)printf("Case #%d: 1 lizard was left behind.\n",iCase);
else printf("Case #%d: %d lizards were left behind.\n",iCase,ans);
}
return ;
}
2015/5/26
hdu 2732 最大流 **的更多相关文章
- POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流)
POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流) Description Yo ...
- HDU 2732 Leapin' Lizards(拆点+最大流)
HDU 2732 Leapin' Lizards 题目链接 题意:有一些蜥蜴在一个迷宫里面,有一个跳跃力表示能跳到多远的柱子,然后每根柱子最多被跳一定次数,求这些蜥蜴还有多少是不管怎样都逃不出来的. ...
- 【解题报告】 Leapin' Lizards HDU 2732 网络流
[解题报告] Leapin' Lizards HDU 2732 网络流 题外话 在正式讲这个题目之前我想先说几件事 1. 如果大家要做网络流的题目,我在网上看到一个家伙,他那里列出了一堆网络流的题目, ...
- HDU 1532 最大流入门
1.HDU 1532 最大流入门,n个n条边,求第1点到第m点的最大流.只用EK做了一下. #include<bits/stdc++.h> using namespace std; #pr ...
- HDU 2732 Leapin' Lizards(最大流)
http://acm.hdu.edu.cn/showproblem.php?pid=2732 题意: 给出n行的网格,还有若干只蜥蜴,每只蜥蜴一开始就在一个格子之中,并且给出蜥蜴每次的最大跳跃长度d. ...
- HDU 2732:Leapin' Lizards(最大流)
http://acm.hdu.edu.cn/showproblem.php?pid=2732 题意:给出两个地图,蜥蜴从一个柱子跳跃到另外一个地方,那么这个柱子就可能会坍塌,第一个地图是柱子可以容忍跳 ...
- hdu 2732 Leapin' Lizards(最大流)Mid-Central USA 2005
废话: 这道题不难,稍微构造一下图就可以套最大流的模板了.但是我还是花了好久才解决.一方面是最近确实非常没状态(托词,其实就是最近特别颓废,整天玩游戏看小说,没法静下心来学习),另一方面是不够细心,输 ...
- hdu 2732 Leapin' Lizards 最大流 拆点 建图
题目链接 题意 给定一张网格,格子中有些地方有柱子,有些柱子上面有蜥蜴. 每个柱子只能承受有限只蜥蜴从上面经过.每只蜥蜴每次能走到相距曼哈顿距离\(\leq k\)的格子中去. 问有多少只蜥蜴能走出网 ...
- Leapin' Lizards [HDU - 2732]【网络流最大流】
题目链接 网络流直接最大流就是了,只是要拆点小心一个点的流超出了原本的正常范围才是. #include <iostream> #include <cstdio> #includ ...
随机推荐
- clog,cout,cerr 输出机制
clog:控制输出,使其输出到一个缓冲区,这个缓冲区关联着定义在 <cstdio> 的 stderr. cerr:强制输出刷新,没有缓冲区. cout:控制输出,使其输出到一个缓冲区,这个 ...
- 转载:Github项目解析(七)-->防止按钮重复点击
不错的东西,记录下... http://46aae4d1e2371e4aa769798941cef698.devproxy.yunshipei.com/qq_23547831/article/deta ...
- 【前端vue开发】vue开发watch检测的使用
<span style="color:#006600;"><div id="app"> <input type="tex ...
- P1986 元旦晚会
一道可以用各种各样的办法做的(水)题 在这里就介绍两种做法 题意: 自己看看吧,很明显的意思,就是求前i个人最少有多少个话筒. 解法1:差分约束 设\(dis[i]\)表示前\(i\)个人最少有多少个 ...
- Javascript之对象的创建
面向对象语言有一个非常显著的标志,那就是它们都有类的概念,通过类之间的继承就可以达到任意创建具有相同属性方法的对象.而在ECMAScript中并没有类的概念,它把对象定义为:无序属性的集合,其属性包含 ...
- Codeforces 981D Bookshelves(按位贪心+二维DP)
题目链接:http://codeforces.com/contest/981/problem/D 题目大意:给你n本书以及每本书的价值,现在让你把n本书放到k个书架上(只有连续的几本书可以放到一个书架 ...
- sql中多层循环示例(有游标)
在需求处理中,我们会遇到需要通过SQL多层循环来处理的问题.如:A表中有8条数据,B表中有10条数据,需要实现A表中的每1条数据对应B表中的10条数据,最后就有了80条数据,从而实现一对多的关系.那如 ...
- javascript数组元素的添加、删除与插入以及参数数组的使用
1.数组元素的添加 push方法在数组的尾部添加元素: var colorArray=new Array(); colorArray.push('red','black','yellow'); //这 ...
- 如何把自己的wordpress网站移到本地修改
有时候wordpress更换模板时,需要修改的地方很多,而且在线修改不是很好.只能把它移动到电脑本地进行修改了.这样修改好就可以直接套用到网站上了. 1.通过服务器控制面板或FTP整站打包,发送到你已 ...
- 微信小程序 跳一跳 外挂 C# winform源码
昨天微信更新了,出现了一个小游戏“跳一跳”,玩了一下 赶紧还蛮有意思的 但纯粹是拼手感的,玩了好久,终于搞了个135分拿了个第一名,没想到过一会就被朋友刷下去了,最高的也就200来分把,于是就想着要是 ...