1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
| #include <bits/stdc++.h> using namespace std; const int maxn = 3010; const int maxm = 2e6+5; const int inf = 0x3f3f3f3f; struct Edge { int v,c,next; } edge[maxm];
int n,m,tot,source,sink,cnt; int head[maxn],dep[maxn],cur[maxn];
void add(int u,int v,int c) { edge[tot].v=v; edge[tot].c=c; edge[tot].next=head[u]; head[u]=tot++; } void addedge(int u,int v,int c) { add(u,v,c); add(v,u,0); }
bool bfs() { queue<int> que; memset(dep,-1,sizeof dep); dep[source] = 0; que.push(source); while (!que.empty()) { int u = que.front(); que.pop(); for (int i=head[u]; i!=-1; i=edge[i].next) { int to = edge[i].v; if (edge[i].c>0 && dep[to] == -1) { dep[to] = dep[u] + 1; que.push(to); if (to == sink) return 1; } } } return dep[sink] != -1; }
int dfs(int u,int dist) { if (u == sink) return dist; for (int &i=cur[u]; i!=-1; i=edge[i].next) { int to = edge[i].v; if (edge[i].c>0 && dep[to]==dep[u]+1) { int temp = dfs(to,min(dist,edge[i].c)); if (temp > 0) { edge[i].c -= temp; edge[i^1].c += temp; return temp; } } } return 0; }
int dfs_test(int u,int delta) { if (u == sink) return delta; int flow = 0; for (int &i=cur[u]; i!=-1; i=edge[i].next) { int to = edge[i].v; if (edge[i].c>0 && dep[to]==dep[u]+1) { int temp = dfs(to,min(delta-flow,edge[i].c)); edge[i].c -= temp; edge[i^1].c += temp; flow += temp; if (delta-flow <= 0) break; } } if (!flow) dep[u] = -1; return flow; }
int Dinic() { int ans = 0; while (bfs()) { for (int i=0; i<cnt; ++i) cur[i] = head[i]; while(1) { int temp = dfs(source,inf); if (!temp) break; ans += temp; } } return ans; }
int main() { memset(head,-1,sizeof head); scanf("%d",&n); source = 0; sink = n+1; int tot_val = 0; for (int i=1; i<=2*n; ++i) { int val; scanf("%d",&val); tot_val += val; if (i <= n) { addedge(source,i,val); } else { addedge(i-n,sink,val); } } scanf("%d",&m); cnt = sink+1; for (int i=1; i<=m; ++i) { int k,c1,c2,to; scanf("%d%d%d",&k,&c1,&c2); tot_val += (c1+c2); addedge(source,cnt++,c1); addedge(cnt++, sink, c2); while (k--) { scanf("%d",&to); addedge(cnt-2,to,inf); addedge(to,cnt-1,inf); } } int maxflow = Dinic(); printf("%d\n",tot_val - maxflow); return 0; }
|