Cod sursa(job #1296252)

Utilizator diana97Diana Ghinea diana97 Data 20 decembrie 2014 18:54:58
Problema Ubuntzei Scor 65
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.18 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

ifstream f ("ubuntzei.in");
ofstream g ("ubuntzei.out");

const int NMAX = 2000 + 1;
const int KMAX = 15 + 1;
const int INF = 0x3fffffff;

int n, m, k;
int distanta[NMAX];
short int special[NMAX];
int distante[KMAX][NMAX];
vector <short int> graf[NMAX];
vector <int> cost[NMAX];
int best[1 << KMAX][NMAX];
queue <short int> Q;

void citeste() {
    f >> n >> m >> k;
    int a, b, c;
    for (int i = 1; i <= k; i++) f >> special[i];
    for (int i = 1; i <= m; i++) {
        f >> a >> b >> c;
        graf[a].push_back(b); cost[a].push_back(c);
        graf[b].push_back(a); cost[b].push_back(c);
    }
}

void bellman_ford(int sursa) {
    Q.push(sursa);
    int nod, d, fiu, l;
    for (int i = 1; i <= n; i++) distanta[i] = INF;
    distanta[sursa] = 0;

    while (!Q.empty()) {
        nod = Q.front();
        Q.pop();
        l = graf[nod].size();
        for (int i = 0; i < l; i++) {
            fiu = graf[nod][i];
            d = cost[nod][i] + distanta[nod];
            if (d < distanta[fiu]) {
                distanta[fiu] = d;
                Q.push(fiu);
            }
        }
    }
}

void rezolva() {
    int nr_config = 1 << k;
    if (!k) {
        bellman_ford(1);
        g << distanta[n];
        return;
    }

    special[0] = 1;
    for (int i = 0; i <= k; i++) {
        bellman_ford(special[i]);
        for (int j = 0; j <= k; j++)
            distante[i][j] = distanta[special[j]];
        distante[i][k + 1] = distanta[n];
    }

    for (int config = 0; config < nr_config; config++)
        for (int i = 0; i <= k; i++) best[config][i] = INF;
    best[0][0] = 0;
    for (int config = 1; config < nr_config; config++) {
        for (int i = 0; i < k; i++)
            if (config & (1 << i)) {
                int config2 = config - (1 << i);
                for (int j = 0; j <= k; j++)
                    best[config][i + 1] = min(best[config][i + 1], best[config2][j] + distante[j][i + 1]);
            }
    }

    int sol = INF;
    for (int i = 1; i <= k; i++)
        sol = min(sol, best[nr_config - 1][i] + distante[i][k + 1]);
    g << sol << '\n';
}

int main() {
    citeste();
    rezolva();
    return 0;
}