답안 #893972

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
893972 2023-12-27T18:04:42 Z borisAngelov Evacuation plan (IZhO18_plan) C++17
41 / 100
4000 ms 34292 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<int>& curr)
{
    if (l > r)
    {
        return;
    }

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

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

        return;
    }

    int mid = (l + r) / 2;

    for (int i = toTry.size() - 1; i >= mid; --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<int> toLeft;
    vector<int> toRight;

    for (int i = 0; i < curr.size(); ++i)
    {
        if (dsu.areConnected(queries[curr[i]].from, queries[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)
    {
        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));
            }
        }
    }

    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();

    vector<int> starting;

    for (int i = 0; i < q; ++i)
    {
        starting.push_back(i);
    }

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

    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<int>&)':
plan.cpp:136:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::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<int>::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:241: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]
  241 |         for (int i = 0; i < g[node].size(); ++i)
      |                         ~~^~~~~~~~~~~~~~~~
plan.cpp:258: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]
  258 |         for (int j = 0; j < g[i].size(); ++j)
      |                         ~~^~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 7260 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 7516 KB Output is correct
5 Correct 3 ms 7516 KB Output is correct
6 Correct 2 ms 7516 KB Output is correct
7 Correct 1 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 5 ms 7516 KB Output is correct
12 Correct 2 ms 7540 KB Output is correct
13 Correct 4 ms 7516 KB Output is correct
14 Correct 7 ms 7752 KB Output is correct
15 Correct 5 ms 7516 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 7260 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 7516 KB Output is correct
5 Correct 3 ms 7516 KB Output is correct
6 Correct 2 ms 7516 KB Output is correct
7 Correct 1 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 5 ms 7516 KB Output is correct
12 Correct 2 ms 7540 KB Output is correct
13 Correct 4 ms 7516 KB Output is correct
14 Correct 7 ms 7752 KB Output is correct
15 Correct 5 ms 7516 KB Output is correct
16 Correct 3187 ms 17216 KB Output is correct
17 Correct 2281 ms 34140 KB Output is correct
18 Correct 208 ms 9924 KB Output is correct
19 Correct 78 ms 22008 KB Output is correct
20 Correct 2497 ms 34292 KB Output is correct
21 Correct 294 ms 24256 KB Output is correct
22 Execution timed out 4024 ms 18640 KB Time limit exceeded
23 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 7256 KB Output is correct
2 Correct 2 ms 7768 KB Output is correct
3 Correct 2 ms 7516 KB Output is correct
4 Correct 2 ms 7516 KB Output is correct
5 Correct 2 ms 7516 KB Output is correct
6 Correct 2 ms 7516 KB Output is correct
7 Correct 1 ms 7516 KB Output is correct
8 Correct 2 ms 7516 KB Output is correct
9 Correct 2 ms 7512 KB Output is correct
10 Correct 2 ms 7512 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 119 ms 18124 KB Output is correct
2 Correct 275 ms 30572 KB Output is correct
3 Correct 267 ms 30384 KB Output is correct
4 Correct 87 ms 16332 KB Output is correct
5 Correct 335 ms 30776 KB Output is correct
6 Correct 264 ms 29504 KB Output is correct
7 Correct 283 ms 30604 KB Output is correct
8 Correct 243 ms 29636 KB Output is correct
9 Correct 305 ms 29636 KB Output is correct
10 Correct 302 ms 30440 KB Output is correct
11 Correct 282 ms 30404 KB Output is correct
12 Correct 302 ms 30744 KB Output is correct
13 Correct 278 ms 30432 KB Output is correct
14 Correct 295 ms 30096 KB Output is correct
15 Correct 267 ms 31680 KB Output is correct
16 Correct 263 ms 30304 KB Output is correct
17 Correct 242 ms 29632 KB Output is correct
18 Correct 246 ms 29772 KB Output is correct
19 Correct 87 ms 16340 KB Output is correct
20 Correct 330 ms 30436 KB Output is correct
21 Correct 245 ms 28856 KB Output is correct
22 Correct 49 ms 15420 KB Output is correct
23 Correct 127 ms 15424 KB Output is correct
24 Correct 54 ms 15424 KB Output is correct
25 Correct 50 ms 15428 KB Output is correct
26 Correct 98 ms 15148 KB Output is correct
27 Correct 98 ms 16336 KB Output is correct
28 Correct 51 ms 15440 KB Output is correct
29 Correct 87 ms 16336 KB Output is correct
30 Correct 53 ms 15428 KB Output is correct
31 Correct 105 ms 16336 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 7260 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 7516 KB Output is correct
5 Correct 3 ms 7516 KB Output is correct
6 Correct 2 ms 7516 KB Output is correct
7 Correct 1 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 5 ms 7516 KB Output is correct
12 Correct 2 ms 7540 KB Output is correct
13 Correct 4 ms 7516 KB Output is correct
14 Correct 7 ms 7752 KB Output is correct
15 Correct 5 ms 7516 KB Output is correct
16 Correct 3187 ms 17216 KB Output is correct
17 Correct 2281 ms 34140 KB Output is correct
18 Correct 208 ms 9924 KB Output is correct
19 Correct 78 ms 22008 KB Output is correct
20 Correct 2497 ms 34292 KB Output is correct
21 Correct 294 ms 24256 KB Output is correct
22 Execution timed out 4024 ms 18640 KB Time limit exceeded
23 Halted 0 ms 0 KB -