이분매칭 : O(V+E)

struct BiMatch {
    bool vst[MAX];
    int match[MAX];     // match[i] <-match-- i
    vector<int> adj[MAX];
    bool dfs(int here) {
        if (vst[here]) return false;
        vst[here] = true;
        for (auto there : adj[here]) {
            if (match[there]<0 || dfs(match[there])) {
                //매칭이 되어있지 않은 정점을 만나거나 이미 매칭된 정점이 다른 정점과 매칭이 가능할 때
                match[there] = here;
                return true;
            }
        }
        return false;
    }
    int bimatch(int cap = 1, int n = MAX-1) { // 1-index
        memset(match, -1, sizeof(match));
        int ret = 0;
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j < cap; ++j) { // st당 몇 번 매칭?
                memset(vst, 0, sizeof(vst));
                if (dfs(i)) ret++;
            }
        }
        return ret;
    }
} BI;

 

디닉 : O(EV^2), 0-1 cap에서 min{O(EV^(2/3), O(E^(3/2))}   (대충 다익스트라랑 비슷하다고 하자 (ainta 피셜))

struct Dinic {
    struct edg {int pos, cap, rev;};
    vector<edg> adj[MAX];
    void clear() { for (int i = 0; i < MAX; i++) adj[i].clear(); }
    void make_edge(int s, int e, int x) {
        adj[s].push_back({e, x, (int) adj[e].size()});
        adj[e].push_back({s, 0, (int) adj[s].size() - 1});
    }
    int dis[MAX], pnt[MAX];
    bool bfs(int src, int sink) {
        memset(dis, 0, sizeof(dis));
        memset(pnt, 0, sizeof(pnt));
        queue<int> que;
        que.push(src);
        dis[src] = 1;
        while (!que.empty()) {
            int x = que.front();
            que.pop();
            for (auto &e : adj[x]) {
                if (e.cap > 0 && !dis[e.pos]) {
                    dis[e.pos] = dis[x] + 1;
                    que.push(e.pos);
                }
            }
        }
        return dis[sink] > 0;
    }
    int dfs(int x, int sink, int f) {
        if (x == sink) return f;
        for (; pnt[x] < adj[x].size(); pnt[x]++) {
            edg e = adj[x][pnt[x]];
            if (e.cap > 0 && dis[e.pos] == dis[x] + 1) {
                int w = dfs(e.pos, sink, min(f, e.cap));
                if (w) {
                    adj[x][pnt[x]].cap -= w;
                    adj[e.pos][e.rev].cap += w;
                    return w;
                }
            }
        }
        return 0;
    }
    ll maxflow(int src, int sink) {
        ll ret = 0;
        while (bfs(src, sink)) {
            int r;
            while ((r = dfs(src, sink, 2e9))) ret += r;
        }
        return ret;
    }
} FW;

'알고리즘 > 정리글' 카테고리의 다른 글

Modulo Integer  (0) 2021.04.13
Policy based data structures  (0) 2021.04.12
그리디  (0) 2021.02.19
기하  (0) 2021.02.19
세그먼트 트리  (0) 2021.01.15

+ Recent posts