BZOJ 1066 [SCOI2007]蜥蜴 (最大流)

题意:

一个方格图里$a_{ij}$为这个格子里柱子的高度,一些有高度的柱子上有一个蜥蜴,每个蜥蜴可以跳到距自己曼哈顿距离<=D的高度不为零的柱子上,同时当前柱子高度减1,蜥蜴的最终目的是跳出格子,问最终有多少蜥蜴跳不出去。

思路:

最大流,源点为S,汇点为T

对每个有高度的柱子拆点id→pid,容量为柱子高度 (id代表跳入,pid代表跳出)

对每个有蜥蜴的柱子,连接s→id,容量为1

对每根有高度的柱子a,以及与这根柱子曼哈顿距离小于D的所有柱子b,连接$pid_a \rightarrow id_b$,容量为inf

对每根有高度的柱子a,如果他到边界的曼哈顿距离小于D,那么他一定能跳出去,连接$pid_a \rightarrow t$,容量为inf

跑一哈,答案为numL-maxFlow

 

板子不太熟。。忘记了加边前要设置tot=1

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional>
    
#define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) 

using namespace std;

typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL;

const db eps = 1e-6;
const int mod = 1e9+7;
const int maxn = 2e6+100;
const int maxm = 2e6+100;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0);

int head[maxn],d[maxn];//
int ver[maxm],edge[maxm],Next[maxm];//edge[i]: c for edge_i
int n, m, s, t, tot, maxflow;
queue<int>q;
void add(int x, int y, int z){
    //printf("  %d %d %d\n",x,y,z);
    ver[++tot]=y,edge[tot]=z,Next[tot]=head[x],head[x]=tot;
    
    ver[++tot]=x,edge[tot]=0,Next[tot]=head[y],head[y]=tot;
}

bool bfs(){
    mem(d,0);
    while(!q.empty())q.pop();
    q.push(s);
    d[s]=1;
    while(!q.empty()){
        int x = q.front();
        q.pop();
        for(int i = head[x]; i; i = Next[i]){
            if(edge[i] && !d[ver[i]]){
            q.push(ver[i]);
            d[ver[i]] = d[x] + 1;
            if(ver[i] == t) return true;
            }
        }
    }
    return false;
}
int dinic(int x, int flow){
    if(x==t) return flow;
    int rest = flow, k;
    for(int i = head[x]; i; i = Next[i]){
        if(edge[i] && d[ver[i]] == d[x]+1){
            k = dinic(ver[i], min(rest, edge[i]));
            if(!k) d[ver[i]] = 0;
            edge[i] -= k;
            edge[i^1] += k;
            rest -= k;
        }
    }
    return flow - rest;
}
char pm[30][30];
char xy[30][30];
int main(){
    int r,c,D;
    scanf("%d %d %d", &r, &c, &D);
    getchar();
    for(int i = 1; i <= r; i++){
        scanf("%s", pm[i]);
    }
    for(int i = 1; i <= r; i++){
        scanf("%s", xy[i]);
    }
    s = 0, t = 1001;
    tot =1;
    for(int i = 1; i <= r; i++){
        for(int j = 0; j < c; j++){
            int id = i*c+j;
            
            int pid = id + 500;//id -> pid
            //printf("1111: %d %d %d %d\n",i, j, id, pid);
        }
    }
    int num = 0;
    for(int i = 1; i <= r; i++){
        for(int j = 0; j < c; j++){
            int id = i*c+j;
            
            int pid = id + 500;//id -> pid
            //printf("1111: %d %d %d %d\n",i, j, id, pid);
            if(xy[i][j]=='L'){
                add(s,id,1);
                num++;
            }
            if(pm[i][j]!='0'){
                add(id,pid,pm[i][j]-'0');
            }
            else continue;
            int hv = 0;
            for(int k = -D; k <= D; k++){
                for(int p = -D; p <= D; p++){
                    if(abs(k)+abs(p)>D)continue;
                    if(k==0 && p==0)continue;
                    int dx = i+k;
                    int dy = j+p;
                    if((dx>r || dx < 1) || (dy >= c || dy < 0)){
                        if(hv)continue;
                        add(pid, t, inf);
                        hv=1;
                        continue;
                    }
                    int iid = dx*c+dy;
                    if(pm[dx][dy]=='0')continue;
                    add(pid, iid, inf);
                }
            }
        }

    }
    int flow = 0;
    maxflow=0;
    while(bfs()){
        while(1){
            flow = dinic(s,inf);
            if(!flow)break;
            maxflow+=flow;
        }
    }
    printf("%d\n",num-maxflow);
    return 0;
}

/*
3 5 1
20000
03211
20000
.....
.LLL.
.....


3 3 1
200
031
200
...
.LL
...

3 3 0
200
031
200
L..
.L.
...
 */

 

posted @ 2018-12-19 17:12  wrjlinkkkkkk  阅读(197)  评论(0编辑  收藏  举报