제출 #90671

#제출 시각아이디문제언어결과실행 시간메모리
90671popovicirobert결혼 문제 (IZhO14_marriage)C++14
72 / 100
1587 ms23556 KiB
#include <bits/stdc++.h>
#define lsb(x) (x & (-x))
#define ll long long
#define ull unsigned long long
#define ld long double
// 217
// 44

using namespace std;

const int MAXN = 30000;

struct MaxFlow {

    const int INF = 1e9;

    struct Edge {
        int nod, id1, id2;
    };

    vector < vector <Edge> > g;
    vector <Edge> from;
    vector <int> cap, vis;
    int n, m;
    int sink, dest;
    int now, ans;

    inline void init(int _n, int _sink, int _dest) {
        n = _n, sink = _sink, dest = _dest;
        m = 0;
        g.resize(n + 1);
        from.resize(n + 1);
        vis.resize(n + 1);
        ans = now = 0;
    }

    inline void addEdge(int x, int y, int c) {
        if(mp[{y, x}]) {
            return ;
        }

        g[x].push_back({y, m, m + 1});
        cap.push_back(c);
        mp[{x, y}] = m;

        g[y].push_back({x, m + 1, m});
        cap.push_back(0);
        mp[{y, x}] = m + 1;

        m += 2;
    }

    inline bool bfs() {
        queue <int> Q;
        now++;
        Q.push(sink);
        vis[sink] = now;
        while(Q.size()) {
            int nod = Q.front();
            Q.pop();
            for(auto it : g[nod]) {
                if(vis[it.nod] != now && cap[it.id1] > 0) {
                    Q.push(it.nod);
                    from[it.nod] = {nod, it.id1, it.id2};
                    vis[it.nod] = now;
                }
            }
        }
        return vis[dest] == now;
    }

    inline int flow() {
        while(bfs()) {
            int nod = dest;
            int mn = INF;
            while(nod != sink) {
                mn = min(mn, cap[from[nod].id1]);
                nod = from[nod].nod;
            }
            nod = dest;
            while(nod != sink) {
                cap[from[nod].id1] -= mn;
                cap[from[nod].id2] += mn;
                nod = from[nod].nod;
            }
            ans += mn;
        }
        return ans;
    }

    map < pair <int, int>, int > mp;
    inline void delEdge(int x, int y) {
        if(x > n) {
            swap(x, y);
        }
        int id1 = mp[{x, y}];
        int id2 = id1 + 1;
        if(cap[id1] == 0) {
            ans--;
            cap[mp[{sink, x}]] = cap[mp[{y, dest}]] = 1;
        }
        cap[mp[{x, sink}]] = cap[mp[{dest, y}]] = 0;
        cap[id1] = cap[id2] = 0;
    }

};

vector <int> g[MAXN + 1];

int main() {
    //ifstream cin("A.in");
    //ofstream cout("A.out");
    int i, n, m, k;
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cin >> n >> m >> k;
    for(i = 1; i <= k; i++) {
        int a, b;
        cin >> a >> b;
        g[a].push_back(b);
    }
    MaxFlow net;
    net.init(n + m + 2, n + m + 1, n + m + 2);
    for(i = 1; i <= n; i++) {
        net.addEdge(net.sink, i, 1);
    }
    for(i = 1; i <= m; i++) {
        net.addEdge(i + n, net.dest, 1);
    }
    int pos = 1;
    ll ans = 0;
    for(i = 1; i <= n; i++) {
        bool ok = 0;
        while(net.flow() < m && pos <= n) {
            for(auto it : g[pos]) {
                net.addEdge(pos, it + n, 1);
            }
            pos++;
            ok = 1;
        }
        pos -= ok;
        if(net.ans == m) {
            ans += n - pos + 1;
        }
        for(auto it : g[i]) {
            net.delEdge(i, it + n);
        }
    }
    cout << ans;
    //cin.close();
    //cout.close();
    return 0;
}

#Verdict Execution timeMemoryGrader output
Fetching results...