Cod sursa(job #1371505)

Utilizator diana97Diana Ghinea diana97 Data 3 martie 2015 21:56:42
Problema Ubuntzei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.31 kb
#include <iostream>
#include <fstream>
#include <queue>

using namespace std;

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

const int INF = (1 << 30);

const int KMAX = 15 + 2;
const int NMAX = 2 * 2000 + 1;



int n, m, k;
short int special[KMAX + 1];
int dist[NMAX];
bool inQ[NMAX];
int d[KMAX + 1][KMAX + 1];
int dp[1 << KMAX][KMAX + 1];
vector <int> graf[NMAX], cost[NMAX];
queue <short int> Q;



void citeste() {
    f >> n >> m;
    f >> k;
    for (int i = 1; i <= k; i++)
        f >> special[i];

    int a, b, c;
    for (int i = 1; i <= m; i++) {
        f >> a >> b >> c;
        graf[a].push_back(b);
        graf[b].push_back(a);

        cost[a].push_back(c);
        cost[b].push_back(c);
    }
}

void bellman_ford(int sursa, int d[]) {
    int c, fiu, l, nod;

    for (int i = 1; i <= n; i++) d[i]= INF, inQ[i] = false;
    d[sursa] = 0;
    Q.push(sursa);
    inQ[sursa] = true;

    while(!Q.empty()) {
        nod = Q.front();

        l = graf[nod].size();
        inQ[nod] = false;

        for (int i = 0; i < l; i++) {
            fiu = graf[nod][i];
            c = d[nod] + cost[nod][i];
            if (d[fiu] > c) {
                d[fiu] = c;
                if (inQ[fiu] == false) {inQ[fiu] = true; Q.push(fiu);}
            }
        }

        Q.pop();
    }
}

void rezolva() {
    int nrconfig = (1 << k);
    int m;

    if (k == 0) {
        bellman_ford(1, dist);
        g << dist[n] << '\n';
        return;
    }


    special[0] = 1;
    special[k + 1] = n;
    k++;

    for (int i = 0; i < k; i++) {
        bellman_ford(special[i], dist);
        for (int j = 0; j <= k; j++) d[i][j] = dist[special[j]];
    }

    k--;

    for (int masca = 0; masca < nrconfig; masca++)
        for (int i = 0; i <= k; i++) dp[masca][i] = INF;
    dp[0][0] = 0;


    for (int masca = 1; masca < nrconfig; masca++) {
        for (int i = 0; i < k; i++) {
            if (masca & (1 << i)) {
                m = masca - (1 << i);
                for (int j = 0; j <= k; j++)
                    if (masca & (1 << j))
                        dp[masca][i + 1] = min(dp[masca][i + 1], dp[m][j] + d[j][i + 1]);
            }
        }
    }

    int sol = INF;
    for (int i = 1; i <= k; i++) sol = min(sol, dp[nrconfig - 1][i] + d[i][k + 1]);

    g << sol;
}

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