牛客练习赛19 D-托米去购物

最裸的最大流,没啥好说的。。

#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\n", sum - ans);
    }
    return 0;
}

/*
*/

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/9226069.html