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