Cod sursa(job #2472156)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 12 octombrie 2019 09:40:14
Problema Amenzi Scor 60
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.01 kb
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

const int N = 150;
const int INF = (int) 1e9;
int n, m, k, p, d[N][N];
vector <int> aib[N];
vector <int> what[N];

int getmax(int i, int p)
{
    int ans = -INF;
    for (int j = p; j >= 1; j -= j & (-j))
    {
        ans = max(ans, aib[i][j]);
    }
    return ans;
}

void upd(int i, int p, int x)
{
    for (int j = p; j < (int) aib[i].size(); j++)
    {
        aib[i][j] = max(aib[i][j], x);
    }
}

struct event
{
    int a;
    int t;
    int c;
    int i;
};

bool operator < (event f, event s)
{
    if (f.t == s.t)
    {
        if (f.a == s.a)
        {
            return f.c > s.c;
        }
        else
        {
            return f.a < s.a;
        }
    }
    else
    {
        return f.t < s.t;
    }
}

int sol[8007];

int main()
{
    freopen ("amenzi.in", "r", stdin);
    freopen ("amenzi.out", "w", stdout);

    cin >> n >> m >> k >> p;

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            d[i][j] = INF;
        }
        d[i][i] = 0;
    }

    for (int i = 0; i < n; i++)
    {
        aib[i].push_back(-INF);
        what[i].push_back(0);
    }

    for (int i = 0; i < m; i++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        a--;
        b--;
        d[a][b] = d[b][a] = c;
    }

    for (int k = 0; k < n; k++)
    {
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
            }
        }
    }

    vector <event> evt;
    for (int i = 0; i < k; i++)
    {
        int a, t, c;
        cin >> a >> t >> c;
        a--;
        evt.push_back({a, t, c, 0});
    }

    for (int i = 0; i < p; i++)
    {
        int a, t;
        cin >> a >> t;
        a--;
        evt.push_back({a, t, -(i + 1), 0});
    }

    evt.push_back({0, 0, INF, 0});
    sort(evt.begin(), evt.end());

    for (auto &it : evt)
    {
        it.i = (int) aib[it.a].size();
        what[it.a].push_back(it.t);
        aib[it.a].push_back(-INF);
    }

    for (auto &it : evt)
    {
        int tmp = it.t, a = it.a;
        int DP = getmax(a, it.i) + max(0, it.c);

        if (it.c < 0)
        {
            sol[-it.c] = DP;
        }

        for (int b = 0; b < n; b++)
        {
            int tmp2 = tmp + d[a][b];
            int l = 1, r = (int) what[b].size() - 1, ans = INF;
            while (l <= r)
            {
                int mid = (l + r) / 2;
                if (what[b][mid] < tmp2)
                {
                    l = mid + 1;
                }
                else
                {
                    ans = mid;
                    r = mid - 1;
                }
            }
            upd(b, ans, DP);
        }
    }

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


}