QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#454559#6546. Greedy Bipartite MatchingpandapythonerTL 981ms101608kbC++207.8kb2024-06-25 03:52:392024-06-25 03:52:42

Judging History

你现在查看的是最新测评结果

  • [2024-06-25 03:52:42]
  • 评测
  • 测评结果:TL
  • 用时:981ms
  • 内存:101608kb
  • [2024-06-25 03:52:39]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;


#define ll long long
#define flt double
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define rep(i, n) for(int i = 0; i < n; i += 1)


const ll inf = 1e18;
mt19937 rnd(234);


struct num {
    vector<pair<int, int>> a;

    num() {}
    num(int x, int y) {
        a = { make_pair(x, y) };
    }


    bool is_zero() {
        return a.empty();
    }


    bool is_nonnegative() {
        if (a.empty()) {
            return true;
        }
        return a[0].second > 0;
    }


    bool is_negative() {
        return !is_nonnegative();
    }
};


num operator+(const num& a, const num& b) {
    num c;
    c.a.reserve((int)a.a.size() + (int)b.a.size());
    int i = 0, j = 0;
    while (i < (int)a.a.size() and j < (int)b.a.size()) {
        if (a.a[i].first < b.a[j].first) {
            c.a.push_back(a.a[i]);
            i += 1;
        } else if (a.a[i].first > b.a[j].first) {
            c.a.push_back(b.a[j]);
            j += 1;
        } else if (a.a[i].second + b.a[j].second != 0) {
            c.a.push_back(make_pair(a.a[i].first, a.a[i].second + b.a[j].second));
            i += 1;
            j += 1;
        } else {
            i += 1;
            j += 1;
        }
    }
    while (i < (int)a.a.size()) {
        c.a.push_back(a.a[i]);
        i += 1;
    }
    while (j < (int)b.a.size()) {
        c.a.push_back(b.a[j]);
        j += 1;
    }
    return c;
}


num operator-(const num& a, const num& b) {
    num c;
    c.a.reserve((int)a.a.size() + (int)b.a.size());
    int i = 0, j = 0;
    while (i < (int)a.a.size() and j < (int)b.a.size()) {
        if (a.a[i].first < b.a[j].first) {
            c.a.push_back(a.a[i]);
            i += 1;
        } else if (a.a[i].first > b.a[j].first) {
            c.a.push_back(make_pair(b.a[j].first, -b.a[j].second));
            j += 1;
        } else if (a.a[i].second - b.a[j].second != 0) {
            c.a.push_back(make_pair(a.a[i].first, a.a[i].second - b.a[j].second));
            i += 1;
            j += 1;
        } else {
            i += 1;
            j += 1;
        }
    }
    while (i < (int)a.a.size()) {
        c.a.push_back(a.a[i]);
        i += 1;
    }
    while (j < (int)b.a.size()) {
        c.a.push_back(b.a[j]);
        j += 1;
    }
    return c;
}


bool operator<(const num& a, const num& b) {
    int i = 0, j = 0;
    while (i < (int)a.a.size() and j < (int)b.a.size()) {
        if (a.a[i].first < b.a[j].first) {
            return (a.a[i].second < 0);
        } else if (a.a[i] > b.a[j]) {
            return (b.a[j].second > 0);
        } else if (a.a[i].second - b.a[j].second != 0) {
            return a.a[i].second < b.a[j].second;
        }
        i += 1;
        j += 1;
    }
    if (i < (int)a.a.size()) {
        return a.a[i].second < 0;
    }
    if (j < (int)b.a.size()) {
        return b.a[i].second > 0;
    }
    return false;
}


struct edge {
    int to;
    num w;
    int f, c;
    int rvi;

    edge() {}
    edge(int to, const num& w, int c, int rvi) : to(to), w(w), f(0), c(c), rvi(rvi) {}

    int rest() const {
        return c - f;
    }
};


namespace flow {
    int n;
    int q;
    vector<vector<edge>> g;


    void build(int _n, int _q) {
        n = _n;
        q = _q;
        g.assign(n, vector<edge>());
    }


    void add_edge(int v, int to, int x = -1) {
        int i = (int)g[v].size();
        int j = (int)g[to].size();
        if (x == -1) {
            g[v].push_back(edge(to, num(), 1, j));
            g[to].push_back(edge(v, num(), 0, i));
        } else {
            g[v].push_back(edge(to, num(x, -1), 1, j));
            g[to].push_back(edge(v, num(x, 1), 0, i));
        }
    }


    vector<num> dist;
    vector<int> usd;


    void dijkstra(int s) {
        dist.assign(n, num(-1, 1));
        dist[s] = num();
        usd.assign(n, false);
        usd[s] = true;
        set<pair<num, int>> q;
        q.insert(make_pair(dist[s], s));
        while (!q.empty()) {
            int v = q.begin()->second;
            usd[v] = true;
            q.erase(q.begin());
            for (auto& e : g[v]) {
                int to = e.to;
                if (usd[to] or e.rest() <= 0) {
                    continue;
                }
                if (dist[v] + e.w < dist[to]) {
                    if (dist[to].a.empty() or dist[to].a[0].first != -1) {
                        q.erase(make_pair(dist[to], to));
                    }
                    dist[to] = dist[v] + e.w;
                    q.insert(make_pair(dist[to], to));
                }
            }
        }
    }


    vector<int> pntr;
    vector<int> dist_bfs;

    void bfs(int s){
        dist_bfs.assign(n, n + 10);
        dist_bfs[s] = 0;
        queue<int> q;
        q.push(s);
        while(!q.empty()){
            int v = q.front();
            q.pop();
            for(auto &e: g[v]){
                int to = e.to;
                if(e.rest() <= 0 or !e.w.is_zero()){
                    continue;
                }
                if(dist_bfs[to] > dist_bfs[v] + 1){
                    dist_bfs[to] = dist_bfs[v] + 1;
                    q.push(to);
                }
            }
        }
    }


    bool dfs(int v, int t) {
        if (v == t) {
            return true;
        }
        usd[v] = true;
        for (int& i = pntr[v]; i < (int)g[v].size(); i += 1) {
            auto& e = g[v][i];
            int to = e.to;
            if (usd[to] or e.rest() <= 0 or !e.w.is_zero()) {
                continue;
            }
            if (dfs(to, t)) {
                e.f += 1;
                g[to][e.rvi].f -= 1;
                usd[v] = false;
                return true;
            }
        }
        return false;
    }


    vector<int> flow(int s, int t) {
        vector<int> result(q);
        num delta = num();
        while (1) {
            dijkstra(s);
            if (!usd[t]) {
                break;
            }
            delta = delta + dist[t];
            if (delta.is_nonnegative()) {
                break;
            }
            assert((int)delta.a.size() == 1);
            rep(v, n) {
                if (!usd[v]) {
                    continue;
                }
                for (auto& e : g[v]) {
                    int to = e.to;
                    if (!usd[to]) {
                        continue;
                    }
                    e.w = e.w + dist[v] - dist[to];
                }
            }
            bfs(s);
            pntr.assign(n, 0);
            usd.assign(n, false);
            while (1) {
                bool ok = dfs(s, t);
                if (!ok) {
                    break;
                }
                result[delta.a[0].first] += -delta.a[0].second;
            }
        }
        for (int i = 1; i < q; i += 1) {
            result[i] += result[i - 1];
        }
        return result;
    }
};



int32_t main() {
    if (1) {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
    }
    int n, q;
    cin >> n >> q;
    flow::build(2 * n + 2, q);
    rep(i, n) {
        flow::add_edge(2 * n, i);
        flow::add_edge(n + i, 2 * n + 1);
    }
    rep(i, q) {
        int t;
        cin >> t;
        rep(j, t) {
            int u, v;
            cin >> u >> v;
            --u;
            --v;
            flow::add_edge(u, n + v, i);
        }
    }
    auto result = flow::flow(2 * n, 2 * n + 1);
    assert((int)result.size() == q);
    rep(i, q) {
        cout << result[i] << " ";
    }
    cout << "\n";
    return 0;
}


/*
3 4
2
1 1
1 2
2
1 1
2 2
2
1 3
3 2
1
3 3

*/

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3556kb

input:

3 4
2
1 1
1 2
2
1 1
2 2
2
1 3
3 2
1
3 3

output:

1 2 2 3 

result:

ok 4 number(s): "1 2 2 3"

Test #2:

score: 0
Accepted
time: 0ms
memory: 3800kb

input:

0 0

output:



result:

ok 0 number(s): ""

Test #3:

score: 0
Accepted
time: 0ms
memory: 3552kb

input:

2 2
0
2
1 2
1 2

output:

0 1 

result:

ok 2 number(s): "0 1"

Test #4:

score: 0
Accepted
time: 962ms
memory: 93032kb

input:

100000 1
200000
78475 45796
32145 46393
92550 13904
73461 34145
96461 92851
56319 77067
77530 84437
76343 51543
77507 99269
76411 89382
1779 61393
43608 96136
84269 74828
14858 35967
32085 94909
19877 175
1482 94391
12424 55020
64369 92588
81296 7903
25433 46033
36294 61129
73556 84837
8419 10215
12...

output:

100000 

result:

ok 1 number(s): "100000"

Test #5:

score: 0
Accepted
time: 941ms
memory: 94956kb

input:

100000 1
200000
56816 52517
2577 76202
40378 1758
50464 66497
15834 50880
9829 16331
80693 9963
51096 17591
15871 35192
91302 65510
90775 57493
11891 8967
44787 41896
3387 35479
93471 47453
84804 93636
90746 34877
18202 38718
7473 34258
36581 19533
13249 27525
6442 69870
8822 61871
94537 67714
41396...

output:

100000 

result:

ok 1 number(s): "100000"

Test #6:

score: 0
Accepted
time: 0ms
memory: 3564kb

input:

4 1
7
2 2
3 3
1 1
4 2
2 3
3 1
4 3

output:

3 

result:

ok 1 number(s): "3"

Test #7:

score: 0
Accepted
time: 282ms
memory: 89048kb

input:

100000 1
199999
25371 25371
85965 85964
416 416
16797 16797
12438 12438
45410 45409
63006 63005
22156 22156
87829 87828
84014 84014
37308 37308
72325 72325
83704 83704
55391 55390
6781 6780
78091 78091
9376 9376
82193 82193
74695 74695
49842 49842
15799 15799
69856 69855
82949 82948
97390 97389
205 ...

output:

100000 

result:

ok 1 number(s): "100000"

Test #8:

score: 0
Accepted
time: 311ms
memory: 88388kb

input:

100000 1
199999
59470 59470
76774 76773
89517 89517
87041 87041
90185 90185
83076 83076
61455 61455
33616 33616
85795 85794
92073 92072
49726 49726
63843 63842
99248 99248
24122 24122
29553 29552
73534 73534
75846 75846
27030 27029
84419 84419
26637 26637
10101 10100
75014 75013
67342 67342
75647 75...

output:

100000 

result:

ok 1 number(s): "100000"

Test #9:

score: 0
Accepted
time: 981ms
memory: 101608kb

input:

100000 1
199999
22285 45796
32145 44931
58735 13904
57137 34145
7549 92851
56319 11875
77530 85279
27040 51543
77507 94258
69266 89382
67074 61393
86160 96136
83228 74828
14858 19501
32085 73640
86885 175
27269 94391
20021 55020
45358 92588
17834 7903
55802 46033
36294 46558
73556 13747
8419 88394
1...

output:

100000 

result:

ok 1 number(s): "100000"

Test #10:

score: 0
Accepted
time: 964ms
memory: 97628kb

input:

100000 1
199999
4851 52517
2577 29251
69017 1758
85855 66497
48301 50880
83742 16331
98932 9963
38731 17591
15871 13961
91302 97596
81693 57493
11891 59333
5077 41896
23575 35479
93471 65246
61977 93636
96141 34877
18202 35367
64058 34258
25589 19533
13249 91004
6442 83449
99192 61871
94537 16903
73...

output:

100000 

result:

ok 1 number(s): "100000"

Test #11:

score: -100
Time Limit Exceeded

input:

100000 1
199997
4415 9894
97824 23182
2551 30097
24322 27913
64552 31862
23073 68076
28494 14953
11400 33367
14514 13085
40869 51446
63170 88054
76550 23848
22657 57759
9479 56985
96440 59224
69954 84962
55443 22220
96520 87619
31746 72821
8800 6061
36912 77572
8970 95816
32991 68335
29931 84159
333...

output:


result: