zoukankan      html  css  js  c++  java
  • 「JSOI2015」圈地

    「JSOI2015」圈地

    传送门

    显然是最小割。

    首先对于所有房子,权值 (> 0) 的连边 (s o i) ,权值 (< 0) 的连边 (i o t) ,然后对于所有的墙,连两条边,连接起墙两边的房子,容量就是修墙的费用,然后直接用权值和 - 最小割就是最大收益。

    参考代码:

    #include <cstring>
    #include <cstdio>
    #define rg register
    #define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
    template < class T > inline T min(T a, T b) { return a < b ? a : b; }
    template < class T > inline void read(T& s) {
        s = 0; int f = 0; char c = getchar();
        while ('0' > c || c > '9') f |= c == '-', c = getchar();
        while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
        s = f ? -s : s;
    }
     
    const int _ = 400 * 400 + 5, __ = 3 * 400 * 400 + 5, INF = 2147483647;
     
    int tot = 1, head[_]; struct Edge { int v, w, nxt; } edge[__ << 1];
    inline void Add_edge(int u, int v, int w) { edge[++tot] = (Edge) { v, w, head[u] }, head[u] = tot; }
    inline void link(int u, int v, int w) { Add_edge(u, v, w), Add_edge(v, u, 0); }
     
    int n, m, x, sum, s, t, dep[_], cur[_];
    
    inline int bfs() {
        static int hd, tl, Q[_];
        memset(dep, 0, sizeof (int) * (t - s + 1));
        hd = tl = 0, Q[++tl] = s, dep[s] = 1;
        while (hd < tl) {
        	int u = Q[++hd];
            for (rg int i = head[u]; i; i = edge[i].nxt) {
                int v = edge[i].v, w = edge[i].w;
                if (dep[v] == 0 && w)
                    dep[v] = dep[u] + 1, Q[++tl] = v;
            }
        }
        return dep[t] > 0;
    }
    
    inline int dfs(int u, int flow) {
        if (u == t) return flow;
        for (rg int& i = cur[u]; i; i = edge[i].nxt) {
        	int v = edge[i].v, w = edge[i].w;
        	if (dep[v] == dep[u] + 1 && w) {
    	        int res = dfs(v, min(w, flow));
    	        if (res) { edge[i].w -= res, edge[i ^ 1].w += res; return res; }
    	    }
        }
        return 0;
    }
     
    inline int Dinic() {
        int res = 0;
        while (bfs()) {
        	for (rg int i = s; i <= t; ++i) cur[i] = head[i];
        	while (int d = dfs(s, INF)) res += d;
        }
        return res;
    }
     
    inline int id(int i, int j) { return (i - 1) * m + j; }
     
    int main() {
    #ifndef ONLINE_JUDGE
        file("cpp");
    #endif
        read(n), read(m), s = 0, t = n * m + 1;
        for (rg int i = 1; i <= n; ++i)
        	for (rg int j = 1; j <= m; ++j) {
    	        read(x), sum += x > 0 ? x : -x;
    	        if (x > 0) link(s, id(i, j), x);
    	        if (x < 0) link(id(i, j), t, -x);
    	    }
        for (rg int i = 1; i <= n - 1; ++i)
    	    for (rg int j = 1; j <= m; ++j)
    	        read(x), link(id(i, j), id(i + 1, j), x), link(id(i + 1, j), id(i, j), x);
        for (rg int i = 1; i <= n; ++i)
    	    for (rg int j = 1; j <= m - 1; ++j)
    	        read(x), link(id(i, j), id(i, j + 1), x), link(id(i, j + 1), id(i, j), x);
        printf("%d
    ", sum - Dinic());
        return 0;
    }
    
  • 相关阅读:
    正面管教读书笔记 05 当心逻辑后果
    正面管教读书笔记 04 重新看待不良行为
    正面管教读书笔记 03 出生顺序的重要性
    正面管教读书笔记 02 几个基本概念
    正面管教读书笔记 01 正面的方法
    Shiro身份认证异常:Authentication failed for token submission
    springboot项目配置类使用@ConfigurationProperties注解时,提示Spring Boot Configuration Annotation Proessor not found in classpath
    mysql的性能优化简介
    mysql的逻辑架构
    CentOS7环境下yum方式安装MySQL5.7
  • 原文地址:https://www.cnblogs.com/zsbzsb/p/12305485.html
Copyright © 2011-2022 走看看