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

题意:有N*M的矩形,每个格点有一个柱子,每根柱子有高度c,允许蜥蜴经过这根柱子c次,开始有一些蜥蜴在某些柱子上,它们要跳出这个矩形,每步最大能跳d个单位,求最少有多少蜥蜴不能跳出这个矩形。
分析:转化为求最多有多少蜥蜴能跳出,则变为最大流问题。经典的建图思路,将每个柱子视作点,将其拆为入点和出点,入点到出点建一条容量为c的边,若一个点距离距离边界小于d,建边。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define mp(x,y) make_pair(x,y)
typedef pair<int,int> PII;

const int INF = 0x3f3f3f3f;
const int maxn = 1e3+5;

bool vis[maxn];
struct Edge{
    int from, to,cap,flow;
};
int cost[maxn];
struct Dinic
{
    int n,m,s,t;
    vector<Edge> edges;
    vector<int> G[maxn];
    bool vis[maxn];
    int d[maxn];
    int cur[maxn];

    void init(int n){
        this->n = n;
        for(int i=0;i<=n;++i){
            G[i].clear();
        }
        edges.clear();
    }

    void AddEdge(int from,int to,int cap){
        edges.push_back((Edge){from,to,cap,0});
        edges.push_back((Edge){to,from,0,0});
        m = edges.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }

    bool BFS(){
        memset(vis,0,sizeof(vis));
        queue<int> q;
        q.push(s);
        d[s] = 0;
        vis[s] = 1;
        while(!q.empty()){
            int x = q.front(); q.pop();
            for(int i=0;i<G[x].size();i++){
                Edge &e = edges[G[x][i]];
                if(!vis[e.to] && e.flow < e.cap){
                    vis[e.to] = 1;
                    d[e.to] = d[x] + 1;//层次图
                    q.push(e.to);
                }
            }
        }
        return vis[t];//能否到汇点,不能就结束
    }
    int DFS(int x,int a)//x为当前节点,a为当前最小残量
    {
        if(x == t || a == 0) return a;
        int flow = 0 , r;
        for(int& i = cur[x];i < G[x].size();i++){
            Edge& e = edges[G[x][i]];
            if(d[x] + 1 == d[e.to] && (r = DFS(e.to , min(a,e.cap - e.flow) ) ) > 0 ){
                e.flow += r;
                edges[G[x][i] ^ 1].flow -= r;
                flow += r;//累加流量
                a -= r;
                if(a == 0) break;
            }
        }
        return flow;
    }
    int MaxFlow(int s,int t){
        this->s = s; 
        this->t = t;
        int flow = 0;
        while(BFS()){
            memset(cur,0,sizeof(cur));
            flow += DFS(s,INF);
        }
        return flow;
    }
}F;
char str[maxn];
int G[22][22];
int h,w,d;

bool out(int x,int y)
{
    if(x<0||x>=h||y<0||y>=w) return true;
    return false;
}

void build(int x,int y)
{
    int all = w*h;
    int ed = 2*w*h+1;
    int u = x*w+y;

    F.AddEdge(x*w+y,x*w+y+all,G[x][y]);
    
    if(x-d<0 ||x+d>=h||y-d<0 ||y+d>=w){
        F.AddEdge(u+all,ed,INF);
        return;
    }
    for(int i=0;i<h;++i){
        for(int j=0;j<w;++j){
            if(i==x && j==y) continue;
            if(abs(x-i)+abs(y-j)<=d){
                F.AddEdge(u+all,i*w+j,INF);
            }
        }
    }
}

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    int N,M,T,cas=1; scanf("%d",&T);
    while(T--){
        int u,v,tmp,base;
        int st,ed;
        scanf("%d %d",&h,&d);
        for(int i=0;i<h;++i){
            scanf("%s",str);
            if(i==0){
                w = strlen(str);
                base = w*h;
                st = 2*h*w,ed = st+1;
                F.init(ed+1);
            }
            for(int j=0;j<w;++j){
                G[i][j] = (int)(str[j]-'0');
            }
        }

        for(int i=0;i<h;++i){
            for(int j=0;j<w;++j){
                if(!G[i][j]) continue;
                build(i,j);
            }
        }

        int tot = 0;
        for(int i=0;i<h;++i){
            scanf("%s",str);
            for(int j=0;j<w;++j){
                char c = str[j];
                if(c=='L'){
                    tot++;
                    u = i*w+j;
                    F.AddEdge(st,u,1);          //源点加边
                }
            }
        }
        int res= tot - F.MaxFlow(st,ed);
        printf("Case #%d: ",cas++);
        if(!res) printf("no lizard was left behind.\n");
        else if(res==1) printf("1 lizard was left behind.\n");
        else printf("%d lizards were left behind.\n",res);
    }
    return 0;
}

posted @ 2018-09-05 16:36  xiuwenL  阅读(107)  评论(0编辑  收藏  举报