废话:

这道题不难,稍微构造一下图就可以套最大流的模板了。但是我还是花了好久才解决。一方面是最近确实非常没状态(托词,其实就是最近特别颓废,整天玩游戏看小说,没法静下心来学习),另一方面是不够细心,输出格式错了大意没有发现死一只和死多只之间的区别,卡在那里动不了。

题意:

在一张n*m的地图中,有一群蜥蜴,这群蜥蜴每次可以跳跃曼哈顿距离d(曼哈顿距离——dis(a, b) = |ax-bx|+|ay-by|,之后所有的距离都是曼哈顿距离),这些蜥蜴只能在地图上的一些柱子上跳跃。柱子i最多可以支持ki次经过。如果柱子i距离地图的边界的距离小于d那么蜥蜴可以从柱子i逃出升天。要求计算最后会有多少蜥蜴葬身图中。

输入:

第一行输入一个整数t,表示共有t组数据。

第二行输入两个整数n,d,表示这组数据中地图有n行,蜥蜴一次最大跳跃距离d。

接下来n行输入地图mp1,地图中的数字表示柱子可以经过的次数,0表示不可以经过。

接下来n行输入地图mp2,其中’.’表示空,’L’表示存在一只蜥蜴。

输出:

首先输出组数”Case #x: “,其中x表示第x组。

如果所有的蜥蜴都可以逃出,那么输出”no lizard was left behind.”

如果只有1只死去,那么输出”1 lizard was left behind.”

如果死去多于1只,那么输出”y lizards were left behind.”y表示死去的蜥蜴数量。

题解:

经过一番变化,我们可以构造出一张有向图,然后使用最大流来解决这个问题。

构造方法如下——

  1. 我们设源点为0,汇点为2*n*m+1(其中n为地图的行,m为地图的列),设图中两点p1到p2的距离,即p1到p2的有向边为mp[p1][p2]。
  2. 将地图mp1中所有的点拆分成两个点,点pij拆分为mp[][]中的点i*m+j+1与n*m+i*m+j+1,添加边mp[i*m+j+1][n*m+i*m+j+1] = mp1[i][j]。这是我们构造图mp中最关键的一步,正是因为有了这个有向边,我们才可以使用最大流来计算这个题。
  3. 对于地图mp1,枚举每个点pij,如果这个点距离地图边界的距离小于等于d,那么添加边mp[n*m+i*m+j+1][2*m*n+1] = mp1[i][j];同时枚举除pij以外的点pkl,如果pij与pkl之间的距离小于等于d那么添加边mp[n*m+i*m+j+1][k*m+l+1] = max(mp1[i][j], mp1[k][l])。
  4. 对于地图mp2,如果某个点pij 的值mp2[i][j] == ‘L’,那么构造边mp[0][i*m+j+1] = 1。

然后计算从源点到汇点的最大流即可,我使用的Dinic算法。

具体见代码——

 #include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std; const int N = ;
const int M = ; int dis[N];
int cur[N];
bool vis[N];
char mp[][][];
int mp2[N][N];
int n, m, d, t;
int ans, sum; inline int Min(int x, int y)
{
return x < y ? x : y;
} void init()
{
memset(mp, , sizeof(mp));
memset(mp2, , sizeof(mp2));
scanf("%d%d", &n, &d);
scanf("%s", mp[][]);
m = strlen(mp[][]);
sum = ;
ans = ;
for(int i = ; i < n; i++)
{
scanf("%s", mp[][i]);
}
for(int i = ; i < n; i++)
{
for(int j = ; j < m; j++)
{
for(int k = ; k < n; k++)
{
for(int l = ; l < m; l++)
{
int mid1 = abs(i-k)+abs(j-l);
if(mid1 <= d && i*m+j+ != k*m+l+) //点pij到点pkl之间距离小于等于d且不是同一点
{
int mid = Min(mp[][i][j], mp[][k][l]);
mp2[n*m+i*m+j+][k*m+l+] = mid; //从点pij到点pkl的边
}
}
}
mp2[i*m+j+][n*m+i*m+j+] = mp[][i][j]-''; //从点pij到点pij的边
if(i < d || j < d || n-i <= d || m-j <= d) mp2[m*n+i*m+j+][*n*m+] = mp[][i][j]-''; //从点pij到汇点的边
}
}
for(int i = ; i < n; i++)
{
scanf("%s", mp[][i]);
for(int j = ; j < m; j++)
{
if(mp[][i][j] == 'L')
{
mp2[][i*m+j+] = ; //从源点到点pij的边
sum++;
}
}
}
m = *n*m+;
} bool bfs()
{
memset(vis, , sizeof(vis));
queue<int> que;
que.push();
dis[] = ;
vis[] = ;
while(!que.empty())
{
int k = que.front();
que.pop();
for(int i = ; i <= m; i++)
{
if(!vis[i] && mp2[k][i] > )
{
vis[i] = ;
dis[i] = dis[k]+;
que.push(i);
}
}
}
return vis[m];
} int dfs(int x, int val)
{
if(x == m || val == ) return val;
int flow = , minn;
for(int& i = cur[x]; i <= m; i++)
{
if(dis[x]+ == dis[i] && (minn = dfs(i, Min(val, mp2[x][i]))) > )
{
mp2[x][i] -= minn;
mp2[i][x] += minn;
flow += minn;
val -= minn;
if(val == ) break;
}
}
return flow;
} void work() //Dinic算法
{
while(bfs())
{
for(int i = ; i <= m; i++) cur[i] = ;
ans += dfs(, M);
}
} void outit(int tm)
{
sum -= ans;
printf("Case #%d: ", tm);
if(!sum) printf("no lizard was left behind.\n");
else if(sum == ) printf("1 lizard was left behind.\n");
else printf("%d lizards were left behind.\n", sum);
} int main()
{
//freopen("test.in", "r", stdin);
scanf("%d", &t);
for(int tm = ; tm <= t; tm++)
{
init();
work();
outit(tm);
}
return ;
}

最大流入门——

http://www.cnblogs.com/mypride/p/4859453.html

hdu 2732 Leapin' Lizards(最大流)Mid-Central USA 2005的更多相关文章

  1. hdu 2732 Leapin' Lizards 最大流 拆点 建图

    题目链接 题意 给定一张网格,格子中有些地方有柱子,有些柱子上面有蜥蜴. 每个柱子只能承受有限只蜥蜴从上面经过.每只蜥蜴每次能走到相距曼哈顿距离\(\leq k\)的格子中去. 问有多少只蜥蜴能走出网 ...

  2. hdu 2732 Leapin' Lizards (最大流 拆点建图)

    Problem Description Your platoon of wandering lizards has entered a strange room in the labyrinth yo ...

  3. POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流)

    POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流) Description Yo ...

  4. HDU 2732 Leapin' Lizards(最大流)

    http://acm.hdu.edu.cn/showproblem.php?pid=2732 题意: 给出n行的网格,还有若干只蜥蜴,每只蜥蜴一开始就在一个格子之中,并且给出蜥蜴每次的最大跳跃长度d. ...

  5. HDU - 2732 Leapin' Lizards (拆点最大流)

    题意:有N*M的矩形,每个格点有一个柱子,每根柱子有高度c,允许蜥蜴经过这根柱子c次,开始有一些蜥蜴在某些柱子上,它们要跳出这个矩形,每步最大能跳d个单位,求最少有多少蜥蜴不能跳出这个矩形. 分析:转 ...

  6. HDU 2732 Leapin' Lizards

    网络最大流+拆点.输出有坑!!! #include<cstdio> #include<cstring> #include<string> #include<c ...

  7. HDU 2732 Leapin&#39; Lizards(拆点+最大流)

    HDU 2732 Leapin' Lizards 题目链接 题意:有一些蜥蜴在一个迷宫里面,有一个跳跃力表示能跳到多远的柱子,然后每根柱子最多被跳一定次数,求这些蜥蜴还有多少是不管怎样都逃不出来的. ...

  8. HDU2732 Leapin' Lizards —— 最大流、拆点

    题目链接:https://vjudge.net/problem/HDU-2732 Leapin' Lizards Time Limit: 2000/1000 MS (Java/Others)    M ...

  9. Leapin' Lizards [HDU - 2732]【网络流最大流】

    题目链接 网络流直接最大流就是了,只是要拆点小心一个点的流超出了原本的正常范围才是. #include <iostream> #include <cstdio> #includ ...

随机推荐

  1. 用Java编写你自己的简单HTTP服务器

    http://blog.csdn.net/yanghua_kobe/article/details/7296156 原文不错. 服务器支持的并发连接数,就是要开多少个线程,每个线程里一个socket监 ...

  2. jquery.flip插件翻转效果

    首先去网站http://lab.smashup.it/flip/下载插件 简单应用: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Tran ...

  3. 270. Closest Binary Search Tree Value

    题目: Given a non-empty binary search tree and a target value, find the value in the BST that is close ...

  4. Fiddler如何抓取使用了SSL或TLS传输的Android App流量

    上篇文章介绍了Burpsuite如何抓取使用了SSL或TLS传输的Android App流量, 那么使用Fiddler的时候其实 也会出现与burpsuite同样的情况,解决方案同样是需要将Fiddl ...

  5. Python命令行解析库argparse

    2.7之后python不再对optparse模块进行扩展,python标准库推荐使用argparse模块对命令行进行解析. 1.example 有一道面试题:编写一个脚本main.py,使用方式如下: ...

  6. 用SQLData读写数据库自定义类型

    如何读写自定义类型?SQLData是个很直观的解决办法 在oracle使用手册上找到了很好的资料 点击打开链接 http://docs.oracle.com/cd/B10501_01/java.920 ...

  7. google protobuf使用

    下载的是github上的:https://github.com/google/protobuf If you get the source from github, you need to gener ...

  8. 程序员必须知道的几个国外IT网站

    1.TheServerSide 这是一个老牌的IT信息网站,从名称上你就能看出,它是关注服务器端编程的,以Java和Java周边信息为主,不过最近它也有向客户端和微软产品扩展的趋势.这个网站最初是以免 ...

  9. PHP 练习租房

    练习:租房子 <body> <form action="test.php" method="post"> <div>区域: ...

  10. 用任务管理器画CPU正弦曲线

    这个最初是在microsoft的<编程之美>中看到的,用你的程序来控制CPU的使用率. 首先是要求写一个用来实现CPU使用率为50%程序. 这个还是很好实现的,只要让你的程序忙的时间课空闲 ...