Cod sursa(job #9687)

Utilizator StTwisterKerekes Felix StTwister Data 27 ianuarie 2007 16:42:07
Problema Amenzi Scor 0
Compilator cpp Status done
Runda Unirea 2007, clasele 11-12 Marime 3.31 kb
#include <stdio.h>
#include <string>
#include <queue>
#include <map>
#include <algorithm>

#define NMAX 151
#define TMAX 3501
#define KMAX 12001

using namespace std;

struct amenda
{
    int nod;
    int t;
    int c;
};

int A[NMAX][NMAX];
int C[NMAX][NMAX];
amenda I[KMAX];
int ind[NMAX+1];
int amenda_max[NMAX];
int maxim[NMAX][TMAX];
int N,M,K,P;

int operator<(const amenda& a, const amenda& b)
{
    return (a.nod<b.nod || (a.nod == b.nod && a.t<b.t));
}

int main()
{
    freopen("amenzi.in", "r", stdin);
    freopen("amenzi.out", "w", stdout);
    
    memset(A, 0x3f, sizeof(A));
    
    // citeste muchiile
    scanf("%d %d %d %d", &N, &M, &K, &P);
    for (int i = 1; i<=N; A[i][0] = 0, ++i);
    for (int i = 0; i<M; ++i)
    {
        int x,y,c;
        scanf("%d %d %d", &x, &y, &c);
        
        ++A[x][0];
        A[x][A[x][0]] = y;
        C[x][A[x][0]] = c;
        
        ++A[y][0];
        A[y][A[y][0]] = x;
        C[y][A[y][0]] = c;
    }
    
    // citeste infractiuniile
    for (int i = 0; i<K; ++i)
    {
        scanf("%d %d %d", &I[i].nod, &I[i].t, &I[i].c);
        if (I[i].t > amenda_max[I[i].nod])
           amenda_max[I[i].nod] = I[i].t;
    }
    
    sort(I, I+K);
    
    int last = 0;

    memset(ind, -1, sizeof(ind));
    
    for (int i = 0; i<K; ++i)
    {
        if (I[i].nod != last)
        {  
           ind[I[i].nod] = i;
           last = I[i].nod;
        }
    }
    ind[N+1] = K;
    
    queue< pair<int,int> > q;
    q.push( make_pair(1, 0) );

    memset(maxim, -1, sizeof(maxim));
    maxim[1][0] = 0;
    
    while (!q.empty())
    {
        pair<int,int> per = q.front();
        int nod_cur = per.first;
        int tp = per.second;
        q.pop();
        
        // astept sa bag o amenda
        
        // parcurg toate amenzile posibile pt nod_cur
        if (ind[nod_cur] >= 0)
        {
            for (int i = ind[nod_cur]; I[i].nod == nod_cur; ++i)
            {
                // daca se incadreaza in timp
                if (I[i].t>=tp)
                {
                   if (maxim[nod_cur][I[i].t]<maxim[nod_cur][tp] + I[i].c)
                   {
                      maxim[nod_cur][I[i].t] = maxim[nod_cur][tp] + I[i].c;
                      q.push( make_pair(nod_cur, I[i].t) );
                   }
                   for (int j = tp+1; j<I[i].t; ++j)
                   {
                       if (maxim[nod_cur][j]<maxim[nod_cur][j-1])
                           maxim[nod_cur][j] = maxim[nod_cur][j-1];
                   }
                   break;
                }
            }
        }

        // merg la toate nodurile vecine
        for (int i = 1; i<=A[nod_cur][0]; ++i)
        {
            if (maxim[A[nod_cur][i]][tp+C[nod_cur][i]] < maxim[nod_cur][tp])
            {
               maxim[A[nod_cur][i]][tp+C[nod_cur][i]] = maxim[nod_cur][tp];
               q.push( make_pair(A[nod_cur][i], tp+C[nod_cur][i]) );
            }
        }
    }
    
    for (int i = 0; i<P; ++i)
    {
        int nod_cur, tp;
        scanf("%d %d", &nod_cur, &tp);
        int m = 0;
        for (int j = tp; j>=0; --j)
        {
            if (maxim[nod_cur][j] > m)
               m = maxim[nod_cur][j];
        }
        printf("%d\n", m);
    }
}