zoukankan      html  css  js  c++  java
  • BZOJ 1066 [SCOI2007]蜥蜴 (最大流)

    题意:

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

    思路:

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

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

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

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

    对每根有高度的柱子a,如果他到边界的曼哈顿距离小于D,那么他一定能跳出去,连接$pid_a ightarrow 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
    ",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
    ",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
    ",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
    ",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.
    ...
     */
  • 相关阅读:
    ES查询直方图聚合区间结果min越界问题
    yarn命令操作
    Hve on Spark left join的hashTable问题
    基于HUE可视化的大数据权限管理
    Android 制作圆角阴影的卡片
    Android 解决问题“Failed to resolve: com.android.support:design:26.1.0”
    Android 修改虚拟键栏背景颜色
    ArrayList的传值问题
    swift 网络请求中含有特殊字符的解决方案
    Android适配器
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/10144525.html
Copyright © 2011-2022 走看看