http://www.spoj.com/problems/PROFIT/
最大权闭合子图:点权之和最大的闭合图。
建图:每一条有向边变为容量为inf,源S到正权点v( wv>0 )的边容量 wv ,负权点v( wv<0 )到汇 T 的边容量 −wv ,零权点v( wv=0 )不与源和汇相连。然后求最小割(SUM-最大流)即为答案。
/*
* Author: yew1eb
* Created Time: 2014年10月31日 星期五 15时39分22秒
* File Name: spoj1476 maximum profit.cpp
*/
#include <ctime>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
const int inf = 1e9;
const ll INF = 1e18;
const double eps = 1e-8;
const double pi = acos(-1.0);
const int maxn = 60010;
const int maxm = 2000010;
struct Edge {
int to, cap, next;
Edge(int _next=0,int _to=0,int _cap=0):next(_next),to(_to),cap(_cap) {}
} edge[maxm];
int n, m, S, T, cnt;
int head[maxn], tot;
int d[maxn];//到汇点的距离下界。
int gap[maxn];
void init()
{
tot = 0;
memset(head, -1, sizeof head );
}
void add(int u,int v,int c, int rc=0)
{
edge[tot] = Edge(head[u], v, c);
head[u] = tot++;
edge[tot] = Edge(head[v], u, rc);
head[v] = tot++;
}
int get_flow(int u, int flow)
{
if(u==T || flow==0)return flow;
int res=0, f;
for(int i=head[u]; ~i; i=edge[i].next) {
int &v = edge[i].to;
if(d[u]>d[v] && (f=get_flow(v,min(flow,edge[i].cap)))>0) {
edge[i].cap -= f;
edge[i^1].cap += f;
res += f;
flow -= f;
if(flow==0) return res;
}
}
if(!(--gap[d[u]]))d[S]=cnt+2;
gap[++d[u]]++;
return res;
}
int isap()
{
int flow = 0;
memset(gap, 0, sizeof gap );
memset(d, 0, sizeof d );
cnt = T-S+1;
gap[0] = cnt;
while(d[S]<cnt) flow += get_flow(S, inf);
return flow;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
// freopen("out.cpp", "w", stdout);
#endif // ONLINE_JUDGE
int t;
int n, m;
scanf("%d", &t);
while(t--){
scanf("%d%d", &n, &m);
S = 0, T = n+m+1;
int u, v, c;
init();
for(int i=1; i<=n; ++i){
scanf("%d", &c);
add(i, T, c);
}
int sum = 0;
for(int i=n+1; i<=n+m; ++i){
scanf("%d%d%d", &u, &v, &c);
add(S, i, c);
sum += c;
add(i, u, inf);
add(i, v, inf);
}
int ans = sum - isap();
printf("%d\n", ans);
}
return 0;
}