Cod sursa(job #1716279)

Utilizator preda.andreiPreda Andrei preda.andrei Data 12 iunie 2016 13:03:36
Problema Ubuntzei Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.46 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>

using namespace std;

#define NMAX 2000
#define LOCALITATI_MAX 15
#define INFINIT 0x3F3F3F3F

vector< pair<int, int> > ad[NMAX + 1];
int distanteMinime[NMAX + 1][NMAX + 1];
int localitati[LOCALITATI_MAX + 1];

int distante[NMAX + 1];
vector<bool> inCoada(NMAX + 1);

void aflaDistante(int indice, int n);
bool cmp(int a, int b);

int main()
{
    FILE *fin = fopen("ubuntzei.in", "r");
    FILE *fout = fopen("ubuntzei.out", "w");

    int n, m;
    fscanf(fin, "%d%d", &n, &m);

    int k;
    fscanf(fin, "%d", &k);
    for(int i = 1; i <= k; ++i)
        fscanf(fin, "%d", &localitati[i]);

    while(m--){
        int x, y, cost;
        fscanf(fin, "%d%d%d", &x, &y, &cost);
        ad[x].push_back(make_pair(y, cost));
        ad[y].push_back(make_pair(x, cost));
    }

    localitati[0] = 1;
    for(int i = 0; i <= k; ++i){
        int loc = localitati[i];
        aflaDistante(loc, n);
        for(int j = 1; j <= n; ++j)
            distanteMinime[loc][j] = distante[j];
    }

    int suma = 0;
    int locCur = 1;
    for(int i = 1; i <= k; ++i){
        int pozUrm = 0;
        for(int j = 1; j <= k; ++j){
            int loc = localitati[j];
            if(loc != 0 && (pozUrm == 0 || distanteMinime[locCur][loc] < distanteMinime[locCur][localitati[pozUrm]]))
                pozUrm = j;
        }

        suma += distanteMinime[locCur][localitati[pozUrm]];
        locCur = localitati[pozUrm];
        localitati[pozUrm] = 0;
    }
    suma += distanteMinime[locCur][n];

    fprintf(fout, "%d", suma);
    return 0;
}

void aflaDistante(int indice, int n){
    priority_queue<int, vector<int>, decltype(&cmp)> q(&cmp);
    q.push(indice);

    memset(distante + 1, 0, n * sizeof(int));
    distante[indice] = 0;

    while(!q.empty()){
        int nod = q.top();
        q.pop();

        inCoada[nod] = false;

        for(auto legatura : ad[nod]){
            int vecin = legatura.first;
            int distNou = distante[nod] + legatura.second;

            if((distante[vecin] == 0 && vecin != indice) || distante[vecin] > distNou){
                distante[vecin] = distNou;
                if(!inCoada[vecin]){
                    q.push(vecin);
                    inCoada[vecin] = true;
                }
            }
        }
    }
}

bool cmp(int a, int b){
    return distante[a] > distante[b];
}