luogu P3410 Tire uma foto (foto fechada com peso máximo para corte mínimo)

luogu P3410 Tire uma foto com a
Insira a descrição da imagem aqui
potência máxima foto fechada com o corte mínimo

Para obter o benefício máximo, podemos subtrair o custo mínimo do benefício total possível, que é o corte mínimo.

#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;
}

Acho que você gosta

Origin blog.csdn.net/weixin_45697774/article/details/108653331
Recomendado
Clasificación