답안 #893949

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
893949 2023-12-27T17:38:53 Z borisAngelov Evacuation plan (IZhO18_plan) C++17
41 / 100
4000 ms 41004 KB
#include <bits/stdc++.h>

using namespace std;

const int maxn = 100005;
const long long inf = (1LL << 61);

int n, m, k, q;

int startCities[maxn];

vector<pair<int, int>> g[maxn];

long long dist[maxn];

vector<long long> toTry;

struct Query
{
    int from;
    int to;
    int idx;

    Query()
    {

    }

    Query(int _from, int _to, int _idx)
    {
        from = _from;
        to = _to;
        idx = _idx;
    }
};

struct DSU
{
    struct Roll
    {
        int *pos;
        int val;
        int t;
    };

    int par[maxn];
    int dep[maxn];

    stack<Roll> rollback;

    void init()
    {
        while (!rollback.empty())
        {
            rollback.pop();
        }

        for (int i = 1; i <= n; ++i)
        {
            par[i] = i;
            dep[i] = 1;
        }
    }

    int root(int node)
    {
        if (node == par[node])
        {
            return node;
        }

        return root(par[node]);
    }

    void connect(int x, int y, int tim)
    {
        x = root(x);
        y = root(y);

        if (x == y)
        {
            return;
        }

        if (dep[x] < dep[y])
        {
            swap(x, y);
        }

        rollback.push({&par[y], par[y], tim});
        par[y] = x;

        if (dep[x] == dep[y])
        {
            rollback.push({&dep[x], dep[x], tim});
            ++dep[x];
        }
    }

    void rollbackSmaller(int tim)
    {
        while (!rollback.empty() && tim >= rollback.top().t)
        {
            *rollback.top().pos = rollback.top().val;
            rollback.pop();
        }
    }

    bool areConnected(int x, int y)
    {
        return root(x) == root(y);
    }
};

DSU dsu;

vector<Query> queries;
long long answers[maxn];

vector<pair<int, int>> byValue[maxn];

void parallelBinarySearch(int l, int r, vector<Query>& curr)
{
    if (l > r)
    {
        return;
    }

    if (curr.empty())
    {
        return;
    }

    if (l == r)
    {
        for (int i = 0; i < curr.size(); ++i)
        {
            answers[curr[i].idx] = toTry[l];
        }

        return;
    }

    int mid = (l + r) / 2;

    for (int i = toTry.size() - 1; i >= mid + 1; --i)
    {
        for (int j = 0; j < byValue[i].size(); ++j)
        {
            dsu.connect(byValue[i][j].first, byValue[i][j].second, i);
        }
    }

    dsu.rollbackSmaller(mid);

    vector<Query> toLeft;
    vector<Query> toRight;

    for (int i = 0; i < curr.size(); ++i)
    {
        if (dsu.areConnected(curr[i].from, curr[i].to) == true)
        {
            toRight.push_back(curr[i]);
        }
        else
        {
            toLeft.push_back(curr[i]);
        }
    }

    parallelBinarySearch(l, mid, toLeft);
    parallelBinarySearch(mid + 1, r, toRight);
}

vector<long long> uniqueDistances()
{
    set<long long> s;
    vector<long long> res;

    for (int i = 1; i <= n; ++i)
    {
        if (s.find(dist[i]) == s.end())
        {
            s.insert(dist[i]);
        }
    }

    for (auto element : s)
    {
        res.push_back(element);
    }

    return res;
}

void fastIO()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}

int main()
{
    fastIO();

    cin >> n >> m;

    for (int i = 1; i <= m; ++i)
    {
        int x, y, w;
        cin >> x >> y >> w;

        g[x].push_back(make_pair(y, w));
        g[y].push_back(make_pair(x, w));
    }

    cin >> k;

    for (int i = 1; i <= k; ++i)
    {
        cin >> startCities[i];
    }

    for (int i = 1; i <= n; ++i)
    {
        dist[i] = inf;
    }

    priority_queue<pair<long long, int>> pq;

    for (int i = 1; i <= k; ++i)
    {
        pq.push(make_pair(0, startCities[i]));
        dist[startCities[i]] = 0;
    }

    while (!pq.empty())
    {
        int node = pq.top().second;
        long long curr = -pq.top().first;
        pq.pop();

        for (int i = 0; i < g[node].size(); ++i)
        {
            long long path = g[node][i].second + curr;
            int to = g[node][i].first;

            if (dist[to] > path)
            {
                dist[to] = path;
                pq.push(make_pair(-path, to));
            }
        }
    }

    /*cout << "check " << endl;

    for (int i = 1; i <= n; ++i)
    {
        cout << dist[i] << ' ';
    }

    cout << endl;*/

    toTry = uniqueDistances();

    for (int i = 1; i <= n; ++i)
    {
        for (int j = 0; j < g[i].size(); ++j)
        {
            if (i < g[i][j].first)
            {
                long long d = min(dist[i], dist[g[i][j].first]);

                int l = 0;
                int r = toTry.size() - 1;

                while (l <= r)
                {
                    int mid = (l + r) / 2;

                    if (toTry[mid] >= d)
                    {
                        r = mid - 1;
                    }
                    else
                    {
                        l = mid + 1;
                    }
                }

                byValue[l].push_back(make_pair(i, g[i][j].first));
            }
        }
    }

    cin >> q;

    for (int i = 1; i <= q; ++i)
    {
        int from, to;
        cin >> from >> to;
        queries.push_back(Query(from, to, i));
    }

    dsu.init();

    parallelBinarySearch(0, toTry.size() - 1, queries);

    for (int i = 1; i <= q; ++i)
    {
        cout << answers[i] << "\n";
    }

    return 0;
}

/*
9 12
1 9 4
1 2 5
2 3 7
2 4 3
4 3 6
3 6 4
8 7 10
6 7 5
5 8 1
9 5 7
5 4 12
6 8 2
2
4 7
5
1 6
5 3
4 8
5 8
1 5
*/

Compilation message

plan.cpp: In function 'void parallelBinarySearch(int, int, std::vector<Query>&)':
plan.cpp:136:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Query>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  136 |         for (int i = 0; i < curr.size(); ++i)
      |                         ~~^~~~~~~~~~~~~
plan.cpp:148:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  148 |         for (int j = 0; j < byValue[i].size(); ++j)
      |                         ~~^~~~~~~~~~~~~~~~~~~
plan.cpp:159:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Query>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  159 |     for (int i = 0; i < curr.size(); ++i)
      |                     ~~^~~~~~~~~~~~~
plan.cpp: In function 'int main()':
plan.cpp:244:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  244 |         for (int i = 0; i < g[node].size(); ++i)
      |                         ~~^~~~~~~~~~~~~~~~
plan.cpp:270:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  270 |         for (int j = 0; j < g[i].size(); ++j)
      |                         ~~^~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 7256 KB Output is correct
2 Correct 2 ms 7516 KB Output is correct
3 Correct 2 ms 7516 KB Output is correct
4 Correct 2 ms 7256 KB Output is correct
5 Correct 2 ms 7516 KB Output is correct
6 Correct 2 ms 7516 KB Output is correct
7 Correct 2 ms 7516 KB Output is correct
8 Correct 2 ms 7516 KB Output is correct
9 Correct 5 ms 7516 KB Output is correct
10 Correct 2 ms 7516 KB Output is correct
11 Correct 4 ms 7516 KB Output is correct
12 Correct 2 ms 7728 KB Output is correct
13 Correct 4 ms 7516 KB Output is correct
14 Correct 5 ms 7516 KB Output is correct
15 Correct 5 ms 7516 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 7256 KB Output is correct
2 Correct 2 ms 7516 KB Output is correct
3 Correct 2 ms 7516 KB Output is correct
4 Correct 2 ms 7256 KB Output is correct
5 Correct 2 ms 7516 KB Output is correct
6 Correct 2 ms 7516 KB Output is correct
7 Correct 2 ms 7516 KB Output is correct
8 Correct 2 ms 7516 KB Output is correct
9 Correct 5 ms 7516 KB Output is correct
10 Correct 2 ms 7516 KB Output is correct
11 Correct 4 ms 7516 KB Output is correct
12 Correct 2 ms 7728 KB Output is correct
13 Correct 4 ms 7516 KB Output is correct
14 Correct 5 ms 7516 KB Output is correct
15 Correct 5 ms 7516 KB Output is correct
16 Correct 3263 ms 19172 KB Output is correct
17 Correct 2448 ms 40812 KB Output is correct
18 Correct 198 ms 10664 KB Output is correct
19 Correct 81 ms 31532 KB Output is correct
20 Correct 2410 ms 41004 KB Output is correct
21 Correct 321 ms 34040 KB Output is correct
22 Execution timed out 4054 ms 21656 KB Time limit exceeded
23 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 7512 KB Output is correct
2 Correct 2 ms 7516 KB Output is correct
3 Correct 2 ms 7256 KB Output is correct
4 Correct 2 ms 7256 KB Output is correct
5 Correct 2 ms 7516 KB Output is correct
6 Correct 2 ms 7516 KB Output is correct
7 Correct 2 ms 7516 KB Output is correct
8 Correct 2 ms 7260 KB Output is correct
9 Correct 2 ms 7516 KB Output is correct
10 Correct 2 ms 7516 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 150 ms 18124 KB Output is correct
2 Correct 270 ms 30504 KB Output is correct
3 Correct 287 ms 30732 KB Output is correct
4 Correct 90 ms 16332 KB Output is correct
5 Correct 291 ms 30848 KB Output is correct
6 Correct 349 ms 29688 KB Output is correct
7 Correct 258 ms 30404 KB Output is correct
8 Correct 247 ms 29792 KB Output is correct
9 Correct 248 ms 29768 KB Output is correct
10 Correct 303 ms 30472 KB Output is correct
11 Correct 298 ms 30592 KB Output is correct
12 Correct 321 ms 30812 KB Output is correct
13 Correct 278 ms 30472 KB Output is correct
14 Correct 263 ms 29800 KB Output is correct
15 Correct 256 ms 30664 KB Output is correct
16 Correct 289 ms 30292 KB Output is correct
17 Correct 250 ms 29632 KB Output is correct
18 Correct 282 ms 29780 KB Output is correct
19 Correct 91 ms 16336 KB Output is correct
20 Correct 268 ms 30284 KB Output is correct
21 Correct 210 ms 28816 KB Output is correct
22 Correct 50 ms 15424 KB Output is correct
23 Correct 123 ms 15564 KB Output is correct
24 Correct 50 ms 15176 KB Output is correct
25 Correct 53 ms 15240 KB Output is correct
26 Correct 105 ms 15488 KB Output is correct
27 Correct 91 ms 16336 KB Output is correct
28 Correct 50 ms 15176 KB Output is correct
29 Correct 96 ms 16336 KB Output is correct
30 Correct 77 ms 15428 KB Output is correct
31 Correct 96 ms 16236 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 7256 KB Output is correct
2 Correct 2 ms 7516 KB Output is correct
3 Correct 2 ms 7516 KB Output is correct
4 Correct 2 ms 7256 KB Output is correct
5 Correct 2 ms 7516 KB Output is correct
6 Correct 2 ms 7516 KB Output is correct
7 Correct 2 ms 7516 KB Output is correct
8 Correct 2 ms 7516 KB Output is correct
9 Correct 5 ms 7516 KB Output is correct
10 Correct 2 ms 7516 KB Output is correct
11 Correct 4 ms 7516 KB Output is correct
12 Correct 2 ms 7728 KB Output is correct
13 Correct 4 ms 7516 KB Output is correct
14 Correct 5 ms 7516 KB Output is correct
15 Correct 5 ms 7516 KB Output is correct
16 Correct 3263 ms 19172 KB Output is correct
17 Correct 2448 ms 40812 KB Output is correct
18 Correct 198 ms 10664 KB Output is correct
19 Correct 81 ms 31532 KB Output is correct
20 Correct 2410 ms 41004 KB Output is correct
21 Correct 321 ms 34040 KB Output is correct
22 Execution timed out 4054 ms 21656 KB Time limit exceeded
23 Halted 0 ms 0 KB -