luogu P3410 Take a picture (closed picture with maximum weight to minimum cut)

luogu P3410 Take a picture with the
Insert picture description here
maximum power closed picture to the minimum cut

To get the maximum benefit, we can subtract the minimum cost from the total possible benefit, which is the minimum cut.

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>

using namespace std;
typedef long long ll;
const int N = 500007, M = 5000007, INF = 0x3f3f3f3f;

int n, m;
int head[N], ver[M], nex[M], tot;
int deep[N];
int cur[N], S, T;
ll maxflow, edge[M];

void add(int x, int y, int z, bool o = 1){
    
    
    ver[tot] = y;
    edge[tot] = z;
    nex[tot] = head[x];
    head[x] = tot ++ ;
    if(o)add(y, x, 0, 0);
}

bool bfs()
{
    
    
    memset(deep, 0x3f, sizeof deep);
    queue<int>q;
    q.push(S), deep[S] = 0, cur[S] = head[S];
    while(q.size())
    {
    
    
        int x = q.front();
        q.pop();
        for(int i = head[x]; ~i; i = nex[i]){
    
    
            int y = ver[i], z = edge[i];
            if(z > 0 && deep[y] == INF){
    
    
                q.push(y);
                deep[y] = deep[x] + 1;
                if(y == T)return true;
            }
        }
    }
    return false;
}

ll dfs(int x, ll flow)
{
    
    
    if(x == T)return flow;
    ll ans = 0, i, k;
    for(i = cur[x]; ~i && flow; i = nex[i]){
    
    
        cur[x] = i;
        int y = ver[i];
        ll z = edge[i];
        if(edge[i] > 0 && (deep[y] == deep[x] + 1))
        {
    
    
            k = dfs(y, min(flow, z));
            if(!k)deep[y] = INF;
            edge[i] -= k;
            edge[i ^ 1] += k;
            ans += k;
            flow -= k;
        }
    }
    return ans;
}

void dinic()
{
    
    
    while(bfs()){
    
    
        for(int i = 1; i <= n + m + 1; ++ i)
            cur[i] = head[i];
        maxflow += dfs(S, INF);
    }

}

int main()
{
    
    
    memset(head, -1, sizeof head);
    scanf("%d%d", &n, &m);
    S = 0, T = n + m + 1;
    ll sum = 0;

    for(int i = 1; i <= n; ++ i){
    
    
        int x;
        scanf("%d", &x);
        sum += x;
        add(S, i, x);
        while(~scanf("%d", &x) && x){
    
    
            add(i, x + n, INF);
        }
    }
    for(int i = 1; i <= m; ++ i){
    
    
        int x;
        scanf("%d", &x);
        add(i + n, T, x);
    }
    dinic();

    ll ans = sum - maxflow;
    printf("%lld\n", ans);
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_45697774/article/details/108653331