洛谷 P2891 [USACO07OPEN]吃饭Dining

\(\quad\) 裸的最大流。

#include <cstdio>
#include <cstring>
#include <queue>

const int MAXN = 4e3 + 19, MAXM = 4e6 + 19;

struct Edge{
    int to, next, c;
}edge[MAXM];

int cnt = -1, head[MAXN];

inline void add(int from, int to, int c){
    edge[++cnt].to = to;
    edge[cnt].c = c;
    edge[cnt].next = head[from];
    head[from] = cnt;
}

int n, f, d;

int dep[MAXN];

int bfs(void){
    std::queue<int>q; q.push(0);
    std::memset(dep, 0, sizeof dep); dep[0] = 1;
    while(!q.empty()){
        int node = q.front(); q.pop();
        for(int i = head[node]; i != -1; i = edge[i].next)
            if(!dep[edge[i].to] && edge[i].c)
                dep[edge[i].to] = dep[node] + 1, q.push(edge[i].to);
    }
    return dep[f + n + n + d + 1];
}

inline int min(const int& a, const int& b){
    return a < b ? a : b;
}

int dfs(int node, int flow){
    if(node == f + n + n + d + 1 || !flow)
        return flow;
    int stream = 0, f;
    for(int i = head[node]; i != -1; i = edge[i].next)
        if(dep[edge[i].to] == dep[node] + 1 && (f = dfs(edge[i].to, min(flow, edge[i].c)))){
            flow -= f, stream += f;
            edge[i].c -= f, edge[i ^ 1].c += f;
            if(!flow)
                break;
        }
    return stream;
}

int dinic(void){
    int flow = 0;
    while(bfs())
        flow += dfs(0, 0x3f3f3f3f);
    return flow;
}

int main(){
    std::memset(head, -1, sizeof head);
    std::scanf("%d%d%d", &n, &f, &d);
    for(int i = 1; i <= f; ++i)
        add(0, i, 1), add(i, 0, 0);
    for(int i = f + 1; i <= f + n; ++i)
        add(i, i + n, 1), add(i + n, i, 0);
    for(int i = f + n + n + 1; i <= f + n + n + d; ++i)
        add(i, f + n + n + d + 1, 1), add(f + n + n + d + 1, i, 0);
    for(int a, b, i = 1; i <= n; ++i){
        int l;
        std::scanf("%d%d", &a, &b);
        while(a--){
            std::scanf("%d", &l);
            add(l, f + i, 1), add(f + i, l, 0);
        }
        while(b--){
            std::scanf("%d", &l);
            add(f + n + i, f + n + n + l, 1), add(f + n + n + l, f + n + i, 0);
        }
    }
    std::printf("%d\n", dinic());
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/natsuka/p/12307029.html