zoukankan      html  css  js  c++  java
  • Bzoj 2127 happiness 最小割

    happiness

    题解:

    将图转换成最小割.

    将割完的图中与S相连的点看做选文科, 与T相连的点看做选理科.

    flow(s, u) = 文科值

    flow(u,t) = 理科值

    假设u 和 v 一起选文科有奖励值z,  flow(s,u) = z/2  flow(s,v) = z/2, flow(u,v) = z/2

    假设u 和 v 一起选理科有奖励值z,  flow(u,t) = z/2  flow(v,t) = z/2, flow(u,v) = z/2

    然后合并边.

    具体理解可以画图看最小割之后的模型.

    剩下的图才是价值.

    #include<bits/stdc++.h>
    using namespace std;
    #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
    #define LL long long
    #define ULL unsigned LL
    #define fi first
    #define se second
    #define pb push_back
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define lch(x) tr[x].son[0]
    #define rch(x) tr[x].son[1]
    #define max3(a,b,c) max(a,max(b,c))
    #define min3(a,b,c) min(a,min(b,c))
    typedef pair<int,int> pll;
    const int inf = 0x3f3f3f3f;
    const int _inf = 0xc0c0c0c0;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const LL _INF = 0xc0c0c0c0c0c0c0c0;
    const LL mod =  (int)1e9+7;
    int a[6][105][105];
    int n, m;
    struct FFFlow{
        const static int N = 105*105;
        static const int M = N << 3;
        int head[N], deep[N], cur[N];
        int w[M], to[M], nx[M];
        int tot;
        void add(int u, int v, int val){
            w[tot]  = val; to[tot] = v;
            nx[tot] = head[u]; head[u] = tot++;
    
    //        w[tot] = 0; to[tot] = u;
    //        nx[tot] = head[v]; head[v] = tot++;
        }
        void Eadd(int u, int v, int val, int p){
            add(u, v, val);
            add(v, u, val * p);
        }
        int bfs(int s, int t){
            queue<int> q;
            memset(deep, 0, sizeof(deep));
            q.push(s);
            deep[s] = 1;
            while(!q.empty()){
                int u = q.front();
                q.pop();
                for(int i = head[u]; ~i; i = nx[i]){
                    if(w[i] > 0 && deep[to[i]] == 0){
                        deep[to[i]] = deep[u] + 1;
                        q.push(to[i]);
                    }
                }
            }
            return deep[t] > 0;
        }
        int Dfs(int u, int t, int flow){
            if(u == t) return flow;
            for(int &i = cur[u]; ~i; i = nx[i]){
                if(deep[u]+1 == deep[to[i]] && w[i] > 0){
                    int di = Dfs(to[i], t, min(w[i], flow));
                    if(di > 0){
                        w[i] -= di, w[i^1] += di;
                        return di;
                    }
                }
            }
            return 0;
        }
    
        int Dinic(int s, int t){
            int ans = 0, tmp;
            while(bfs(s, t)){
                for(int i = 0; i <= t; i++) cur[i] = head[i];
                while(tmp = Dfs(s, t, inf)) ans += tmp;
            }
            return ans;
        }
        void init(){
            memset(head, -1, sizeof(head));
            tot = 0;
        }
    
    }Flow;
    int main(){
        Flow.init();
        scanf("%d%d", &n, &m);
        int ans = 0;
        for(int k = 0; k < 6; ++k){
            int x = n, y = m;
            if(k == 2 || k == 3) --x;
            if(k == 5 || k == 4) --y;
            for(int i = 1; i <= x; ++i)
                for(int j = 1; j <= y; ++j){
                    scanf("%d", &a[k][i][j]);
                    ans += a[k][i][j];
                }
        }
        int s = 0, t = n * m + 1;
        for(int i = 1; i <= n; ++i){
            for(int j = 1; j <= m; ++j){
                Flow.Eadd(s, (i-1)*m + j, a[0][i][j] * 2 + a[2][i-1][j] + a[2][i][j] + a[4][i][j-1] + a[4][i][j], 0);
                Flow.Eadd((i-1)*m + j, t, a[1][i][j] * 2 + a[3][i-1][j] + a[3][i][j] + a[5][i][j-1] + a[5][i][j], 0);
                if(i > 1) Flow.Eadd((i-1)*m+j, (i-2)*m+j, a[2][i-1][j] + a[3][i-1][j], 1);
                if(j > 1) Flow.Eadd((i-1)*m+j, (i-1)*m+j-1, a[4][i][j-1] + a[5][i][j-1], 1);
            }
        }
        ans -= Flow.Dinic(s, t) / 2;
        printf("%d
    ", ans);
        return 0;
    }
    View Code

      

  • 相关阅读:
    HDU 1058 Humble Numbers
    HDU 1160 FatMouse's Speed
    HDU 1087 Super Jumping! Jumping! Jumping!
    HDU 1003 Max Sum
    HDU 1297 Children’s Queue
    UVA1584环状序列 Circular Sequence
    UVA442 矩阵链乘 Matrix Chain Multiplication
    DjangoModels修改后出现You are trying to add a non-nullable field 'download' to book without a default; we can't do that (the database needs something to populate existing rows). Please select a fix:
    opencv做的简单播放器
    c++文件流输入输出
  • 原文地址:https://www.cnblogs.com/MingSD/p/11254013.html
Copyright © 2011-2022 走看看