最裸的最大流,没啥好说的。。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int, int> using namespace std; const int N = 1000 + 7; const int M = 1e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 +7; int n, m, tot, S, T, sum, head[N << 1], level[N << 1], a[N << 1], b[N << 1]; struct node { int u, v, w, nx; } edge[M << 2]; void add(int u, int v, int w) { edge[tot].u = u; edge[tot].v = v; edge[tot].w = w; edge[tot].nx = head[u]; head[u] = tot++; } bool bfs() { memset(level, 0, sizeof(level)); queue<int> que; level[S] = 1; que.push(S); while(!que.empty()) { int u = que.front(); que.pop(); if(u == T) return true; for(int i = head[u]; ~i; i = edge[i].nx) { int v = edge[i].v; if(level[v] || edge[i].w <= 0) continue; level[v] = level[u] + 1; que.push(v); } } return false; } int dfs(int u, int p) { if(u == T) return p; int ret = 0; for(int i = head[u]; ~i; i = edge[i].nx) { int v = edge[i].v, w = edge[i].w; if(level[v] != level[u] + 1 || w <= 0) continue; int f = dfs(v, min(p - ret, w)); ret += f; edge[i].w -= f; edge[i ^ 1].w += f; if(ret == p) break; } if(!ret) level[u] = 1; return ret; } int Dinic() { int ans = 0; while(bfs()) ans += dfs(S, inf); return ans; } void init() { tot = 0; sum = 0; memset(head, -1, sizeof(head)); } int main(){ int cas; scanf("%d", &cas); while(cas--) { init(); scanf("%d%d", &n, &m); S = 0, T = n + m + 1; for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); add(i, T, a[i]); add(T, i, 0); sum += a[i]; } for(int i = 1; i <= m; i++) { scanf("%d", &b[i]); add(S, i + n, b[i]); add(i + n, S, 0); } for(int i = 1; i <= m; i++) { int k; scanf("%d", &k); for(int j = 1; j <= k; j++) { int id; scanf("%d", &id); add(i + n, id, inf); add(id, i + n, 0); } } int ans = Dinic(); printf("%d ", sum - ans); } return 0; } /* */