Cod sursa(job #25147)

Utilizator StTwisterKerekes Felix StTwister Data 4 martie 2007 11:04:16
Problema Magazin Scor 0
Compilator cpp Status done
Runda preONI 2007, Runda 3, Clasele 11-12 Marime 2.82 kb
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <queue>

using namespace std;

#define pii pair<int, int>
#define pipii pair< pii, int>
#define mp(x,y,z) make_pair(make_pair(x,y),z)

#define INF 0x3f3f3f3f

#define NMAX 3501
#define MMAX 27
#define PMAX 50001

int maxim[NMAX];
int minim[NMAX];
int d[NMAX][NMAX][2];
int ob[NMAX][MMAX];
int P,N,M,D;

int cmp(const void *i, const void *j)
{
  return ((int *)i)-((int *)j);
}

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

    memset(d, 0x3f, sizeof(d));
    memset(minim, 0x3f, sizeof(minim));
    memset(maxim, 0, sizeof(maxim));

    scanf("%d %d %d %d", &P, &N, &M, &D);

    for (int i = 0; i<P; ++i)
    {
        int x, y;
        scanf("%d %d", &x, &y);
        ob[x][++ob[x][0]] = y;
        if (y>maxim[x])
            maxim[x] = y;
        if (y<minim[x])
            minim[x] = y;
    }

    for (int i = 1; i<=M; ++i)
    {
        qsort(ob+i+1, ob[i][0], sizeof(int), cmp);
    }

    queue< pipii > Q;

    Q.push(mp(1,0,0));
    d[1][0][0] = 0;

    while (!Q.empty())
    {
        pipii per1 = Q.front();
        Q.pop();
        pii per = per1.first;
        int i = per.first;
        int j = per.second;
        int k = per1.second;

        // merg la culuaru urmator fara sa vizitez
        if (i<N && d[i+1][j][k] > d[i][j][k] + D)
        {
            d[i+1][j][k] = d[i][j][k] + D;
            Q.push(mp(i+1,j,k));
        }

        // merg la culuaru anterior fara sa vizitez
        if (i>1 && d[i-1][j][k] > d[i][j][k] + D)
        {
            d[i-1][j][k] = d[i][j][k] + D;
            Q.push(mp(i-1,j,k));
        }

        // vizitez culuaru j, fara sa traversez
        if (j+1==i)
        {
            int val;
            if (k==0)
            {
                if (maxim[i] == 0)
                    val = d[i][j][k];
                else
                    val = d[i][j][k] + (2*maxim[i]);
                if (d[i][i][k] > val)
                {
                    d[i][i][k] = val;
                    Q.push(mp(i,i,k));
                }
            }
            else
            {
                if (minim[i] == INF)
                    val = d[i][j][k];
                else
                    val = d[i][j][k] + (2*(M+1-minim[i]));
                if (d[i][i][k] > val)
                {
                    d[i][i][k] = val;
                    Q.push(mp(i,i,k));
                }
            }
        }

        // traversez culuaru j
        if (j+1==i)
        {
            if (d[i][i][1-k] > d[i][j][k] + M + 1)
            {
                d[i][i][1-k] = d[i][j][k] + M + 1;
                Q.push(mp(i,i,1-k));
            }
        }


    }

    printf("%d\n", d[N][N][0]);

}