Submission #1209035

#TimeUsernameProblemLanguageResultExecution timeMemory
1209035dima2101Robot (JOI21_ho_t4)C++20
34 / 100
3094 ms47088 KiB
#pragma GCC optimize("O3")
#pragma GCC target("avx,avx2")
#include <bits/stdc++.h>
#define int long long

struct Vert
{
    int stop;
    int cost;
    int color;
    int ind;
    Vert() = default;
    Vert(int stop, int cost, int color, int ind) : stop(stop), cost(cost), color(color), ind(ind) {};
};

signed
main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);

    int n, m;
    std::cin >> n >> m;

    std::vector<std::vector<Vert>> g(n);
    for (int i = 0; i < m; i++)
    {
        int a, b;
        int c, p;
        std::cin >> a >> b >> c >> p;
        a--, b--;
        g[a].push_back(Vert(b, p, c, i));
        g[b].push_back(Vert(a, p, c, i));
    }

    std::vector<std::map<int, int>> dist(n);
    dist[0][-1] = 0;
    std::set<std::pair<int, std::pair<int, int>>> s;
    s.insert({dist[0][-1], {0, -1}});
    while (s.size() > 0)
    {
        auto v = s.begin()->second;
        // std::cout << v.first << ' ' << v.second << std::endl;
        s.erase(s.begin());

        std::map<int, int> all;
        for (auto u : g[v.first])
        {
            if (u.ind != v.second)
            {
                all[u.color] += u.cost;
            }
        }
        for (auto u : g[v.first])
        {
            int now = u.cost;
            if (u.ind == v.second)
                continue;

            if (dist[u.stop].find(u.ind) == dist[u.stop].end() || dist[u.stop][u.ind] > dist[v.first][v.second] + now)
            {
                s.erase(std::make_pair(dist[u.stop][u.ind], std::make_pair(u.stop, u.ind)));
                dist[u.stop][u.ind] = dist[v.first][v.second] + now;
                s.insert(std::make_pair(dist[u.stop][u.ind], std::make_pair(u.stop, u.ind)));
            }

            now = std::min(u.cost, all[u.color] - u.cost);
            if (dist[u.stop].find(-1) == dist[u.stop].end() || dist[u.stop][-1] > dist[v.first][v.second] + now)
            {
                s.erase(std::make_pair(dist[u.stop][-1], std::make_pair(u.stop, -1)));
                dist[u.stop][-1] = dist[v.first][v.second] + now;
                s.insert(std::make_pair(dist[u.stop][-1], std::make_pair(u.stop, -1)));
            }
        }
    }
    int min = 1e18;
    for (auto i : dist[n - 1])
    {
        min = std::min(min, i.second);
    }
    if (min == 1e18)
    {
        std::cout << -1;
        return 0;
    }
    std::cout << min;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...