Cod sursa(job #1608977)

Utilizator dariusdariusMarian Darius dariusdarius Data 22 februarie 2016 14:58:21
Problema Amenzi Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.8 kb
#include <algorithm>
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
const int MAX_N = 156;
const int MAX_K = 12005;

int cost[MAX_N][MAX_N];
vector< pair<int, int> > taxes[MAX_N];
int dp[MAX_K];

struct Tax {
    int time, place, value;
    inline bool operator < (const Tax &other) const {
        return time < other.time;
    }

} tax[MAX_K];

int get_index(const vector< pair<int, int> > &v, int time) {
    int left = 0, right = v.size() - 1, last = v.size();
    while (left <= right) {
        int middle = (left + right) / 2;
        if (v[middle].first <= time) {
            last = middle;
            left = middle + 1;
        } else {
            right = middle - 1;
        }
    }
    if (last == static_cast<int>(v.size())) {
        return -1;
    }
    return last;
}

int main() {
    ifstream fin("amenzi.in");
    ofstream fout("amenzi.out");
    int n, m, k, p, a, b, c;
    fin >> n >> m >> k >> p;
    for (int i = 1; i <= n; ++ i) {
        for (int j = 1; j <= n; ++ j) {
            cost[i][j] = 1 << 29;
        }
        cost[i][i] = 0;
    }
    for (int i = 1; i <= m; ++ i) {
        fin >> a >> b >> c;
        cost[a][b] = min(cost[a][b], c);
        cost[b][a] = min(cost[b][a], c);
    }
    for (int k = 1; k <= n; ++ k) {
        for (int i = 1; i <= n; ++ i) {
            for (int j = 1; j <= n; ++ j) {
                cost[i][j] = min(cost[i][j], cost[i][k] + cost[k][j]);
            }
        }
    }
    for (int i = 1; i <= k; ++ i) {
        fin >> tax[i].place >> tax[i].time >> tax[i].value;
    }
    sort(tax + 1, tax + k + 1);
    taxes[1].push_back(make_pair(0, 0));
    for (int i = 1; i <= k; ++ i) {
        if (cost[1][tax[i].place] > tax[i].time) {
            dp[i] = 0;
        } else {
            dp[i] = tax[i].value;
            for (int j = 1; j <= n; ++ j) {
                int last = get_index(taxes[j], tax[i].time - cost[j][tax[i].place]);
                if (last == -1) {
                    continue;
                }
                dp[i] = max(dp[i], taxes[j][last].second + tax[i].value);
            }
        }
        taxes[tax[i].place].push_back(make_pair(tax[i].time, max(dp[i], taxes[tax[i].place].empty() ? 0 : taxes[tax[i].place].back().second)));
    }
    int place, time, best;
    for (int i = 1; i <= p; ++ i) {
        fin >> place >> time;
        if (cost[1][place] > time) {
            fout << "-1\n";
            continue;
        }
        best = 0;
        for (int j = 1; j <= n; ++ j) {
            int last = get_index(taxes[j], time - cost[j][place]);
            if (last == -1) {
                continue;
            }
            best = max(best, taxes[j][last].second);
        }
        fout << best << "\n";
    }
    return 0;
}