Cod sursa(job #1379678)

Utilizator diana97Diana Ghinea diana97 Data 6 martie 2015 18:55:01
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.4 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

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

const int INF = (1 << 30);
const int NMAX = 2000 + 1;
const int KMAX = 16;

int n, m, k;
int special[KMAX + 2];
int d[NMAX];
int dist[KMAX + 1][KMAX + 1];
int dp[(1 << KMAX)][KMAX];
vector <int> graf[NMAX], cost[NMAX];
priority_queue < pair <int, int> > pq;

void citeste() {
    int a, b, c;
    f >> n >> m;
    f >> k;
    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);
        graf[b].push_back(a);

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

void dijkstra(int src, int d[]) {
    int fiu, l, nod, c, c2;
    pair <int, int> p;

    for (int i = 1; i <= n; i++) d[i] = INF;
    d[src] = 0;

    p.first = 0; p.second = src;
    pq.push(p);

    while(!pq.empty()) {
        p = pq.top();
        pq.pop();
        c = -p.first;
        nod = p.second;
        l = graf[nod].size();

        for (int i = 0; i < l; i++) {
            fiu = graf[nod][i];
            c2 = cost[nod][i] + c;
            if (c2 < d[fiu]) {
                d[fiu] = c2;
                p.first = -c2;
                p.second = fiu;
                pq.push(p);
            }
        }
    }
}

void rezolva() {
    special[0] = 1;
    special[k + 1] = n;

    if (k == 0) {
        dijkstra(1, d);
        g << d[n];
        return;
    }

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

    int config, configmax = 1 << k, m, aux;


    for (int config = 0; config < configmax; config++)
        for (int i = 0; i <= k; i++) dp[config][i] = INF;
    dp[0][0] = 0;

    for (int config = 1; config < configmax; config++)
        for (int i = 0; i < k; i++) {
            if (!(config & (1 << i))) continue;
            m = config ^ (1 << i);
            aux = dp[m][0] + dist[0][i + 1];
            for (int j = 0; j < k; j++)
                if (m & (1 << j))
                aux = min(aux, dp[m][j + 1] + dist[j + 1][i + 1]);
            dp[config][i + 1] = aux;
        }

    aux = INF;
    for (int i = 1; i <= k; i++)
        aux = min(aux, dp[configmax - 1][i] + dist[i][k + 1]);

    g << aux;
}

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