zoukankan      html  css  js  c++  java
  • bzoj 1497 最小割

    思路:最小割好难想啊,根本想不到。。

    S -> 用户群 = c[ i ]

    基站 -> T = p[ i ] 

    用户群 -> a[ i ] = inf

    用户群 -> b[ i ] = inf

    然后求最小割,答案就是全部收益的和 - 最小割。

    为什么可以这样呢,对于每个用户群,我们可以不选他,就是把(S -> 用户群)这条边断掉,或者选他,就是把

    (用户群 -> a[ i ] = inf ,用户群 -> b[ i ] = inf)就是把这两条边断掉。 这样求最小割就能得到答案。

    稍微学了一下最大权闭合图, ans =  tot - c (tot 为权值为正的点的和,c 为最小割)。

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define pii pair<int, int>
    
    using namespace std;
    
    const int N = 6e4 + 7;
    const int M = 2e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    
    int n, m, S, T, sum, tot, p[N], a, b, c, level[N], head[N];
    
    struct Edge {
        int to, w, nx;
    }edge[M << 1];
    
    void add(int u, int v, int w) {
        edge[tot].to = v;
        edge[tot].w = w;
        edge[tot].nx = head[u];
        head[u] = tot++;
    }
    
    bool bfs() {
        memset(level, 0, sizeof(level));
        queue<int> que;
        que.push(S), level[S] = 1;
    
        while(!que.empty()) {
            int u = que.front(); que.pop();
            if(u == T) return true;
    
            for(int i = head[u]; ~i; i = edge[i].nx) {
                int v = edge[i].to, w = edge[i].w;
                if(level[v] || w <= 0) continue;
                level[v] = level[u] + 1;
                que.push(v);
            }
        }
        return false;
    }
    
    int dfs(int u, int p) {
        if(u == T) return p;
        int ret = 0;
        for(int i = head[u]; ~i; i = edge[i].nx) {
            int v = edge[i].to, w = edge[i].w;
            if(level[v] != level[u] + 1 || w <= 0) continue;
            int f = dfs(v, min(p - ret, w));
            ret += f;
            edge[i].w -= f;
            edge[i ^ 1].w += f;
            if(ret == p) break;
        }
    
        if(!ret) level[u] = 1;
        return ret;
    }
    
    int Dinic() {
        int ans = 0;
        while(bfs()) ans += dfs(S, inf);
        return ans;
    }
    
    void init() {
        tot = 0; sum = 0;
        memset(head, -1, sizeof(head));
    }
    
    int main() {
        init();
        scanf("%d%d", &n, &m);
        S = 0, T = n + m + 1;
    
        for(int i = 1; i <= n; i++) {
            scanf("%d", &p[i]);
            add(i + m, T, p[i]);
            add(T, i + m, 0);
        }
    
        for(int i = 1; i <= m; i++) {
            scanf("%d%d%d", &a, &b, &c);
            add(S, i, c), add(i, S, 0);
            add(i, a + m, inf), add(a + m, i, 0);
            add(i, b + m, inf), add(b + m, i, 0);
            sum += c;
        }
        int ans = Dinic();
        printf("%d
    ", sum - ans);
        return 0;
    }
    /*
    */
  • 相关阅读:
    centos7 部署kubernetes 1.20.1
    Pulse Width Modulation (PWM) interface
    imx6的IOMUX配置方法
    Linux下巧用转义符来完成多阶攻击
    记录一次半失败的php代码审计
    通过钉钉网页上的js学习xss打cookie
    PostMessage xss学习和挖掘
    解决Android微信支付官方demo运行失败
    Android集成银联支付,提示java.lang.UnsatisfieldLinkError错误
    解决 Plugin with id 'com.github.dcendents.android-maven' not found.
  • 原文地址:https://www.cnblogs.com/CJLHY/p/9276305.html
Copyright © 2011-2022 走看看