luogu P3410 Take a picture with the
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;
}