• bzoj1066: [SCOI2007]蜥蜴


    最大流,首先建模。 设每个石柱分为出节点和入节点。

    1.设一个虚拟源点,与每个初始有蜥蜴的石柱连一条容量为1的边。

    2.设一个虚拟汇点,与每个能跳出来的石柱连一条容量为INF的边。

    3.每一对距离小于d的点,出节点和入节点连一条容量为INF的边。

    4.每个点的入节点和出节点连一条容量为石柱高度的边。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    const int maxn = 1000 + 10;
    const int maxm = 100000 + 10;
    const int INF = 0x3f3f3f3f;
    
    int n,m,d,S,T,vid=0,cnt=0,p=0;
    int h[maxn];
    int id[25][25][2];
    int to[maxm],next[maxm],f[maxm];
    int dist[maxn],gap[maxn];
    char tmp[25];
    
    int abs(int x) {
        return (x > 0 ? x : -x);
    }
    
    void add(int u,int v,int F) {
        to[++p] = v; f[p] = F; next[p] = h[u]; h[u] = p;
        to[++p] = u; f[p] = 0; next[p] = h[v]; h[v] = p;
    }
    
    int ISAP(int u,int flow) {
        if(u == T) return flow;
        
        int cur = 0,aug,mindist = vid;
            
        for(int i = h[u]; ~i; i = next[i]) {
            if(f[i] && dist[to[i]]+1 == dist[u]) {
                aug = ISAP(to[i],min(f[i],flow-cur));
                f[i] -= aug; 
                f[i^1] += aug; 
                cur += aug;
                if(cur == flow || dist[S] >= vid) 
                    return cur;
            }
        }
        
        if(cur == 0) {
            if(!--gap[dist[u]]) {
                dist[S] = vid;
                return cur;
            }
            for(int i = h[u]; ~i; i = next[i]) if(f[i])
                mindist = min(mindist,dist[to[i]]);
            ++gap[dist[u]=mindist+1];
        }
        return cur;
    }
    
    int flow() {
        int res = 0;
        gap[0] = vid;
        while(dist[S] < vid) 
            res += ISAP(S,INF);
        return res;
    }
    
    
    void build() {
        memset(h,-1,sizeof(h));
        p = -1;
        
        scanf("%d%d%d",&n,&m,&d);
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++) {
                id[i][j][0] = ++vid;
                id[i][j][1] = ++vid;
            }
        S = ++vid; T = ++vid;
        
        for(int x1 = 1; x1 <= n; x1++)
        for(int y1 = 1; y1 <= m; y1++) {
            for(int x2 = 1; x2 <= n; x2++)
            for(int y2 = 1; y2 <= m; y2++)
                if(abs(x1-x2) + abs(y1-y2) <= d) 
                if(x1 != x2 || y1 != y2) 
                    add(id[x1][y1][1],id[x2][y2][0],INF);
            if(x1 - d < 1 || x1 + d > n || y1 - d < 1 || y1 + d > m)
                add(id[x1][y1][1],T,INF); 
        }
        
        for(int i = 1; i <= n; i++) {
            scanf("%s",tmp+1);
            for(int j = 1; j <= m; j++) 
                add(id[i][j][0],id[i][j][1],tmp[j]-'0');
        }
        
        for(int i = 1; i <= n; i++) {
            scanf("%s",tmp+1);
            for(int j = 1; j <= m; j++)
                if(tmp[j] == 'L') {
                    add(S,id[i][j][0],1);
                    cnt++;
                }
        }
        
    }
    
    void solve() {
        printf("%d
    ",cnt - flow());
    }
    
    int main() {
        build();
        solve();
        return 0;
    }
  • 相关阅读:
    postfix发信提示 Error: too many connectino from
    postfix 设置邮件头翻译,本域邮件不进行邮件头翻译,仅发送至外网的进行邮件头翻译?
    postfix 如何设置邮件头翻译的功能
    postfix 如何设置邮件头翻译的功能
    Oracle VM VirtualBox如何设置网络地址转换NAT
    python提取百度经验<标题,发布时间,平均流量,总流量,具体的链接>
    css 需要阴影的效果
    django POST表单的使用
    Vim中如何使用正则进行搜索
    Nginx 如何设置反向代理
  • 原文地址:https://www.cnblogs.com/invoid/p/5373449.html
Copyright © 2020-2023  润新知