hdu 2732 Leapin' Lizards (最大流)★

来源:互联网 发布:在线网络测速 编辑:程序博客网 时间:2024/06/10 02:04

题目意思看起来比较难懂。

题目是说一个n*m的迷宫中,有每个格子有柱子。柱子高度为0~3,高度为0的柱子是不能站的(高度为0就是没有柱子)

在一些有柱子的格子上有一些蜥蜴,一次最多跳距离d,相邻格子的距离是1,只要跳出迷宫就是安全的。

这个距离是曼哈顿距离(好像是的)。

蜥蜴一次最多跳距离d,但是起跳的地方的柱子高度会减一,一个柱子同一时间只能有一个蜥蜴

要求最少几个不能逃出迷宫。

具体意思看题目吧,很多描述不清呢~~还是英语好啊

做法就是最大流。

要拆点,两个点的容量就是柱子的高度。

加一个源点和汇点。

#include <set>#include <map>#include <stack>#include <queue>#include <deque>#include <cmath>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF  0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-9#define maxn 100100#define MOD 1000000007const int MAXN = 100010;const int MAXM = 400010;struct Edge{    int to,next,cap,flow;} edge[MAXM];int tot,n,m;int head[MAXN];int gap[MAXN],dep[MAXN];int pre[MAXN],cur[MAXN];void init(){    tot = 0;    memset(head,-1,sizeof(head));}void add_edge(int u,int v,int w,int rw = 0){    edge[tot].to = v;    edge[tot].cap = w;    edge[tot].flow = 0;    edge[tot].next = head[u];    head[u] = tot++;    edge[tot].to = u;    edge[tot].cap = rw;    edge[tot].flow = 0;    edge[tot].next = head[v];    head[v] = tot++;}int sap(int start,int en,int N){    memset(gap,0,sizeof(gap));    memset(dep,0,sizeof(dep));    memcpy(cur,head,sizeof(head));    int u = start;    pre[u] = -1;    gap[0] = N;    int ans = 0;    while(dep[start] < N)    {        if(u == en)        {            int Min = INF;            for(int i = pre[u]; i != -1; i = pre[edge[i^1].to])                if(Min > edge[i].cap - edge[i].flow)                    Min = edge[i].cap - edge[i].flow;            for(int i = pre[u]; i != -1; i = pre[edge[i^1].to])            {                edge[i].flow += Min;                edge[i^1].flow -= Min;            }            u = start;            ans += Min;            continue;        }        int flag = 0;        int v;        for(int i = cur[u]; i != -1; i = edge[i].next)        {            v = edge[i].to;            if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u])            {                flag = 1;                cur[u] = pre[v] = i;                break;            }        }        if(flag)        {            u = v;            continue;        }        int Min = N;        for(int i = head[u]; i != -1; 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 + 1;        gap[dep[u]]++;        if(u != start)            u = edge[pre[u]^1].to;    }    return ans;}char s[22][22];int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int t,C = 1;    scanf("%d",&t);    int d;    while(t--)    {        scanf("%d%d",&n,&d);        init();        for(int i = 0; i < n; i++)            scanf("%s",s[i]);        m = strlen(s[0]);        for(int i = 0; i < n; i++)            for(int j = 0; j < m; j++)            {                int pos = i * m + j;                add_edge(2*pos,2*pos+1,s[i][j]-'0');                for(int k = 1; k <= d; k++)                    for(int l = 0; l <= k; l++)                    {                        for(int f1 = -1; f1 < 3; f1 += 2)                            for(int f2 = -1; f2 < 3; f2 += 2)                            {                                int x = i + l * f1;                                int y = j + (k-l) * f2;                                if(x < 0 || y < 0 || x >= n || y >= m)                                    add_edge(2*pos+1,1000,INF);                                else                                    add_edge(2*pos+1,2*x*m+2*y,s[i][j]-'0');                            }                    }            }        int num = 0;        for(int i = 0; i < n; i++)            scanf("%s",s[i]);        for(int i = 0; i < n; i++)            for(int j = 0; j < m; j++)            {                if(s[i][j] == '.')                    continue;                num++;                int pos = i * m + j;                add_edge(1001,2*pos,1);            }        int ans = num-sap(1001,1000,2*n*m+2);        if(!ans)            printf("Case #%d: no lizard was left behind.\n",C++);        else if(ans == 1)            printf("Case #%d: %d lizard was left behind.\n",C++,ans);        else            printf("Case #%d: %d lizards were left behind.\n",C++,ans);    }    return 0;}




0 0
原创粉丝点击