您的位置:首页 > 其它

hdu2732 Leapin' Lizards

2016-02-20 20:14 405 查看
题目的大意是有个n*m的grid,每个位置上都有柱子,柱子有一定的高度,有一群lizard想逃出这个grid,lizard一次最远可以跳d。

grid的四边是安全的,每个柱子一次上面最多有一只lizard,lizard可以跳到一个可以跳到且上面没有lizard的柱子上面同时它原来所在的柱子的高度会-1,为0时就不能再往上面跳了。

思路就是把柱子拆点,容量为其高度。lizard可以一次性从其跳到安全区的话就和汇点t连接,容量为inf;上面有人的话就和源点s连接,容量为1。

两个柱子的距离在d之内也连接起来,容量为inf。

/*****************************************
Author      :Crazy_AC(JamesQi)
Time        :2016
File Name   :
*****************************************/
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <climits>
using namespace std;
#define MEM(x,y) memset(x, y,sizeof x)
#define pk push_back
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> ii;
typedef pair<ii,int> iii;
const double eps = 1e-10;
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int maxn = 1100;
const int maxm = 1400000;
char mp1[maxn][maxn],mp2[maxn][maxn];
int n, d, m;
int s, t;
int head[maxn], cap[maxm], flow[maxm], nxt[maxm],pnt[maxm];
int ecnt;
inline void Addedge(int u,int v,int c) {
pnt[ecnt] = v, flow[ecnt] = 0, cap[ecnt] = c;
nxt[ecnt] = head[u], head[u] = ecnt++;

pnt[ecnt] = u, flow[ecnt] = 0, cap[ecnt] = 0;
nxt[ecnt] = head[v], head[v] = ecnt++;
}
inline void Input() {
scanf("%d%d",&n,&d);

for (int i = 1;i <= n;++i)
scanf("%s",mp1[i] + 1);

for (int i = 1;i <= n;++i)
scanf("%s",mp2[i] + 1);

m = strlen(mp1[1] + 1);
s = n*m*2+1,t = s + 1;

memset(head, -1,sizeof head);
ecnt = 0;
}
inline int Getmap() {
//拆点
for (int i = 1;i <= n;++i) {
for (int j = 1;j <= m;++j) {
if (mp1[i][j] - '0') {//柱子上面可以跳
Addedge((i-1)*m+j, n*m+(i-1)*m+j, mp1[i][j] - '0');
}
}
}

int cnt = 0;
for (int i = 1;i <= n;++i) {
for (int j = 1;j <= m;++j) {
if (mp2[i][j] == 'L') {//这个位置上有人
Addedge(s, (i-1)*m+j, 1);cnt++;
}
}
}

for (int i = 1;i <= n;++i) {
for (int j = 1;j <= m;++j) {
if (i <= d || j <= d || j > m - d || i > n - d)
Addedge((i-1)*m+j + n*m, t, INF);
}
}

for (int i = 1;i <= n;++i) {
for (int j = 1;j <= m;++j) {
for (int l = 1;l <= n;++l) {
for (int r = 1;r <= m;++r) {
if (!(i==l && j==r) && abs(i-l) + abs(j-r) <= d)
Addedge((i-1)*m+j+n*m,(l-1)*m+r, INF);
}
}
}
}
return cnt;
}

int dis[maxn];
bool vis[maxn];

bool spfa() {
queue<int> que;
memset(dis, -1,sizeof dis);
memset(vis, false,sizeof vis);
que.push(s);
dis[s] = 0;
vis[s] = true;
while(!que.empty()) {
int u = que.front();
que.pop();
for (int i = head[u];i != -1;i = nxt[i]) {
int v = pnt[i];
if (cap[i] - flow[i] > 0 && dis[v] == -1) {
dis[v] = dis[u] + 1;
que.push(v);
}
}
}
return dis[t] != -1;
}

int dfs(int u,int a) {
if (u == t || a == 0) return a;
int ret = 0,f;
for (int i = head[u];i != -1;i = nxt[i]) {
int v = pnt[i];
if (dis[v] > dis[u] && (f = dfs(v, min(a, cap[i] - flow[i]))) > 0) {
ret += f;
a -= f;
flow[i] += f;
flow[i^1] -= f;
if (a==0)break;
}
}
return ret;
}

inline int dinic() {
int ret = 0;
while(spfa()) {
ret += dfs(s, INF);
}
return ret;
}
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int tt;
scanf("%d",&tt);
int icase = 0;
while(tt--) {
Input();
int cnt = Getmap();
int ans = dinic();
// printf("cnt = %d, ans = %d\n",cnt,ans);
printf("Case #%d: ", ++icase);
if (cnt == ans) printf("no lizard was left behind.\n");
if (ans + 1 == cnt) printf("1 lizard was left behind.\n");
if (ans + 1 < cnt) printf("%d lizards were left behind.\n", cnt - ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: