Cod sursa(job #3274855)

Utilizator BledeaAlexBledea Alexandru BledeaAlex Data 8 februarie 2025 11:55:14
Problema Radiatie Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.2 kb
#include <bits/stdc++.h>

using namespace std;

const int N_MAX = 301;
int N, M, Q;

int R[N_MAX];
int nodes[N_MAX];

struct Edge
{
    int risc, len;

    inline bool operator< (const Edge& rhs) const
    {
        return risc > rhs.risc || (risc == rhs.risc && len < rhs.len);
    }

    Edge(int _risc, int _len) :
        risc(_risc), len(_len) {}
};

vector<Edge> rd[N_MAX][N_MAX];

void SetInput(string name)
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    (void)!freopen((name + ".in").c_str(), "r", stdin);
    (void)!freopen((name + ".out").c_str(), "w", stdout);
}

void ReadInput()
{
    cin >> N >> M >> Q;

    for(int i = 1; i <= N; i++)
    {
        cin >> R[i];
        nodes[i] = i;
    }

    for(int i = 0, v1, v2, len; i < M; i++)
    {
        cin >> v1 >> v2 >> len;
        if(v1 == v2) continue;
        rd[v1][v2].emplace_back(0, len);
        rd[v2][v1].emplace_back(0, len);
    }
}

inline void AddPathLen(Edge& E, set<Edge>& S)
{
    set<Edge>::iterator it = S.lower_bound(Edge(E.risc, 0));
    if(it == S.end())
    {
        it = prev(S.end());
        E.risc = it->risc;
    }
    E.len += it->len;
}

inline void AddEdgeToSet(Edge& E, set<Edge>& S)
{
    set<Edge>::iterator it = S.lower_bound(Edge(E.risc, 0));

    if(it != S.end())
    {
        if(it->len <= E.len) /// nu are rost sa adaugam acest drum
            return;

        if(it->risc == E.risc) /// inlocuim muchia de acelasi risc dar cu lungime mai mare
            S.erase(it);
    }

    it = S.insert(E).first;

    if(it == S.begin())
        return;
}

void Solve()
{
    sort(nodes + 1, nodes + N + 1, [&](int a, int b)
         {
            return R[a] < R[b];
         });

    for(int cnt = 1; cnt <= N; cnt++)
        for(int i = 1, k = nodes[cnt]; i <= N; i++)
            for(int j = 1; j <= N; j++)
            {
                if(i == j || i == k || j == k)
                    continue;

                if(rd[i][k].empty() || rd[k][j].empty())
                    continue;

                Edge temp = Edge(R[k], 0);

                temp.len += rd[i][k].back().len;
                temp.len += rd[k][j].back().len;

                /// Adaugam noua muchie

                if(rd[i][j].empty())
                {
                    rd[i][j].emplace_back(temp);
                    continue;
                }

                if(rd[i][j].back().len <= temp.len) /// nu are rost sa adaugam acest drum
                    continue;

                if(rd[i][j].back().risc == temp.risc)
                    rd[i][j].back() = temp;
                else
                    rd[i][j].emplace_back(temp);
            }

    int i, j, r;
    vector<Edge>::reverse_iterator it;

    while(Q--)
    {
        cin >> i >> j >> r;

        if(i == j)
        {
            cout << "0\n";
            continue;
        }

        it = lower_bound(rd[i][j].rbegin(), rd[i][j].rend(), Edge(r, 0));

        if(it == rd[i][j].rend())
            cout << "-1\n";
        else
            cout << it->len << '\n';
    }
}

int main()
{
    SetInput("risc");

    ReadInput();
    Solve();

    return 0;
}