POJ 1466 Girls and Boys (网络流Dinic)

来源:互联网 发布:python的time.sleep 编辑:程序博客网 时间:2024/05/29 19:22

从来就没有会过二分图匹配, 今天带来又一二分图匹配的水题网络流做法
跑的有点慢, 是直接dinic, 无优化, 博主暂时不会
思路:
1.建图时拆点, 将每一个人强行变成两边中的元素, one is 1~n, other is n+1~2n然后对于题目给的关系就直接两个连边,
2.由于这样求出的流量是我们把边加了两次的结果, 所以我们求出的匹配数是结果÷2, 题目求的是最大独立点集, 就用节点数-结果/2

#include <queue>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int N = 1010;const int M = 4*N*N;const int oo = ~0U >> 1;#define next Next#define begin Begin#define rep(i, s, t) for(int i = s; i <= t; ++i)#define erep(i, u) for(int i = begin[u]; i^(-1); i = next[i])struct Dinic {    int S, T, n, c[M], dep[N];    int e, begin[N], next[M], to[M];    void init() {        e = 0; S = 0; T = 2*n+1;        rep(i, S, T) begin[i] = -1;    }    void add(int x, int y, int f) {        to[e] = y;        next[e] = begin[x];        begin[x] = e;        c[e++] = f;    }    void add_flow(int x, int y, int f) {        add(x, y, f); add(y, x, 0);    }    queue<int> q;    bool part() {        rep(i, S, T) dep[i] = -1;        q.push(S); dep[S] = 0;        while(!q.empty()) {            int u = q.front(), v; q.pop();            erep(i, u)                if(c[i]>0 && dep[v = to[i]] == -1)                    dep[v] = dep[u]+1, q.push(v);        }        return dep[T] ^ (-1);    }    int dfs(int u, int max_flow) {        int v, t;        if(u == T) return max_flow;        erep(i, u)            if(dep[u]+1 == dep[v=to[i]] && c[i] > 0 && (t=dfs(v, min(max_flow, c[i])))) {                c[i] -= t, c[i^1] += t;                return t;            }        return 0;    }    int dinic(int res = 0, int t = 0) {        while(part()) {            while((t=dfs(S, oo)))                res += t;        }        return res;    }    void solve() {        while(~scanf("%d", &n)) {            init();            rep(i, 1, n) {                add_flow(S, i, 1);                char s;                int u, len, k;                scanf("%*d: (%d)", &len);                while(len--) scanf("%d", &u), add_flow(i, u+n+1, 1);                add_flow(i+n, T, 1);            }            printf("%d\n", n-dinic()/2);        }    }}T;int main() {#ifndef ONLINE_JUDGE    freopen("IP.in", "r", stdin);    freopen("OP.out", "w", stdout);#endif    T.solve();    return 0;}
1 0
原创粉丝点击