Cod sursa(job #2236771)

Utilizator giotoPopescu Ioan gioto Data 30 august 2018 15:30:55
Problema Amenzi Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.54 kb
#include <bits/stdc++.h>
using namespace std;

int n, m, k, p;
int d[155][3505];

queue <pair <int, int> > q;
set <pair <int, int> > am[155];
vector <pair <int, int> > v[155];

inline void wutm8(){
    for(int i = 1; i <= n ; ++i)
        for(int j = 0; j <= 3500 ; ++j) d[i][j] = -2000000000;

    d[1][0] = 0;
    q.push({1, 0});
    for(auto it : am[1]) d[1][it.first] = it.second;

    while(!q.empty()){
        int nod = q.front().first, timp = q.front().second;
        q.pop();
        for(auto it : v[nod]){
            if(timp + it.second > 3500) continue ;
            if(d[it.first][timp + it.second] < d[nod][timp]){
                q.push({it.first, timp + it.second});
                d[it.first][timp + it.second] = d[nod][timp];

                set <pair <int, int> > :: iterator it2 = am[it.first].lower_bound({timp + it.second, 0});
                int Last = timp + it.second, val = d[nod][timp];
                for(it2; it2 != am[it.first].end() ; ++it2){
                    for(int i = Last; i <= it2->first ; ++i) {
                        if(d[it.first][i] > val) break;
                        d[it.first][i] = max(d[it.first][i], val);
                    }
                    Last = it2->first;
                    if(d[it.first][it2->first] < val + it2->second){
                        d[it.first][it2->first] = val + it2->second;
                        val += it2->second;
                        q.push({it.first, it2->first});
                    }
                }
                for(int i = Last; i <= 3500 ; ++i){
                    if(d[it.first][i] > val) break ;
                    d[it.first][i] = max(d[it.first][i], val);
                }
            }
        }
    }
}
int main()
{
    freopen("amenzi.in", "r", stdin);
    freopen("amenzi.out", "w", stdout);

    scanf("%d%d%d%d", &n, &m, &k, &p);
    int x, y, c;
    for(int i = 1; i <= m ; ++i){
        scanf("%d%d%d", &x, &y, &c);
        v[x].push_back({y, c});
        v[y].push_back({x, c});
    }
    for(int i = 1; i <= k ; ++i){
        scanf("%d%d%d", &x, &y, &c);
        set <pair <int, int> > :: iterator it = am[x].lower_bound({y, 0});
        if(it != am[x].end()) c += it->second, am[x].erase(it);
        am[x].insert({y, c});
    }

    wutm8();

    for(int i = 1; i <= n ; ++i)
        for(int j = 1; j <= 3500 ; ++j)
            d[i][j] = max(d[i][j], d[i][j - 1]);
    for(int i = 1; i <= p ; ++i){
        scanf("%d%d", &x, &y);
        printf("%d\n", max(d[x][y], -1));
    }

    return 0;
}