zoukankan      html  css  js  c++  java
  • bzoj2132

    最小割

    套路最小割。。。

    盗一波图 来自GXZ神犇

    对于这样的图,我们要么割ai,bj,要么割bi,aj,要么割ai,ci+cj,aj,要么割bi,ci+cj,bj,然后这样建图跑最小割就行了

    但这不是重点,这道题我t了大概一个月,不知道为什么,怎么和别人比对代码好像没有什么差异,结果发现判断delta=0不能放在for循环里,否则会很慢。。。俞勇的红书不靠谱啊。。。怪不得我的网络流那么慢。。。

     
    #include<bits/stdc++.h>
    using namespace std;
    const int N = 10010, inf = 1000000010;
    const int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};
    int head[N], d[N], q[N], iter[N];
    struct edge {
        int nxt, to, f;
    } e[N * 50];
    int n, cnt = 1, source, sink, ans, m; 
    #define id(i, j) (i - 1) * m + j
    int read()
    {
        int x = 0, f = 1; char c = getchar();
        while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
        while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
        return x * f;
    }
    void link(int u, int v, int f)
    {
        e[++cnt].nxt = head[u];
        head[u] = cnt;
        e[cnt].to = v;
        e[cnt].f = f;
    }
    void insert(int u, int v, int f)
    {
        link(u, v, f);
        link(v, u, 0);
    }
    bool bfs()
    {
        queue<int> q;
        q.push(source);
        memset(d, 0, sizeof(d));
        d[source] = 1;
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            for(int i = head[u]; i; i = e[i].nxt) if(e[i].f && !d[e[i].to])
            {
                d[e[i].to] = d[u] + 1;
                q.push(e[i].to);
                if(e[i].to == sink) return true;
            }
        }
        return false;
    }
    int dfs(int u, int delta)
    {
        if(u == sink || delta == 0) return delta;
        int ret = 0;
        for(int &i = iter[u]; i; i = e[i].nxt) if(e[i].f && d[e[i].to] == d[u] + 1)
        {
            int x = dfs(e[i].to, min(e[i].f, delta));
            if(x == 0) d[e[i].to] = 0;
            e[i].f -= x;
            e[i ^ 1].f += x;
            delta -= x;
            ret += x;
            if(delta == 0) return ret;
        }
        return ret;
    }
    int dinic()
    {
        int ret = 0;
        while(bfs())
        {
            for(int i = source; i <= sink; ++i) iter[i] = head[i];
            ret += dfs(source, inf); 
        }
        return ret;
    }
    int main()
    {
        scanf("%d%d", &n, &m);
        sink = n * m + 1; 
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= m; ++j)
            {
                int x, a = id(i, j);
                scanf("%d", &x);
                ans += x;
                if((i + j) & 1) insert(source, a, x);
                else insert(a, sink, x);
            }
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= m; ++j)
            {
                int x, a = id(i, j);
                scanf("%d", &x);
                ans += x;
                if((i + j) & 1) insert(a, sink, x);
                else insert(source, a, x);
            }
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= m; ++j)
            {
                int x, a = id(i, j), b;
                scanf("%d", &x);
                for(int k = 0; k < 4; ++k)
                {
                    int xx = i + dx[k], yy = j + dy[k];
                    b = id(xx, yy);
                    if(xx > 0 && xx <= n && yy > 0 && yy <= m) 
                    {
                        ans += x;
                        insert(a, b, x);
                        insert(b, a, x);                
                    }
                }
            }
        printf("%d
    ", ans - dinic());
        return 0;
    }
    View Code
  • 相关阅读:
    微信小程序学习随笔
    SqlServer索引假脱机的解决
    web服务器出现大量CLOSE_WAIT连接的前因后果
    SqlServer和mysql字段拼接方法
    使用beego创建员工加班调休系统
    在c#程序中初步使用redis
    使用golang实现批量发送面试邀请邮件
    记c# rabbitmq的使用
    项目中使用mongodb的尝试
    手机集成支付宝支付功能的注意事项
  • 原文地址:https://www.cnblogs.com/19992147orz/p/7441336.html
Copyright © 2011-2022 走看看