Cod sursa(job #1111364)

Utilizator manutrutaEmanuel Truta manutruta Data 18 februarie 2014 20:23:59
Problema Ubuntzei Scor 65
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.59 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>
#include <queue>
using namespace std;

#define MAXN 2005
#define MAXK 17
#define inf 0x3f3f3f3f

typedef vector< pair<int, int> >::iterator iter;

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

int n, m, k;
int c[MAXK];
vector< pair<int, int> > G[MAXN];
int src[MAXN], d[MAXK][MAXN];
int cost[1 << MAXK][MAXN]; // cost[i][j] = costul minim al unui drum care incepe
    // in nodul 1, trece prin toate nodurile multimea i si se termina in j.
bitset<MAXN> viz;
priority_queue< pair<int, int> > pq;

void dijkstra(int nod, int *dist)
{
    for (int i = 1; i <= n; i++) {
        dist[i] = inf;
    }
    viz.reset();

    dist[nod] = 0;
    pq.push(make_pair(0, nod));
    while (!pq.empty()) {
        int nd = pq.top().second;
        pq.pop();

        if (viz[nd] == true) {
            continue;
        }
        viz[nd] = true;

        for (iter it = G[nd].begin(); it != G[nd].end(); it++) {
            if (dist[it->first] > dist[nd] + it->second) {
                dist[it->first] = dist[nd] + it->second;
                pq.push(make_pair(-dist[it->first], it->first));
            }
        }
    }
}

int hamilton()
{
    for (int i = 1; i < (1 << k); i++) {
        bool cont = false;
        for (int j = 0; j < k; j++) {
            if (i == (1 << j)) {
                cost[i][j] = src[c[j]];
                cont = true;
                break;
            }
        }

        if (cont == true) {
            continue;
        }

        for (int j = 0; j < k; j++) {
            cost[i][j] = inf;
            if (i & (1 << j)) {
                for (int l = 0; l < k; l++) {
                    if (l != j && (i & (1 << l))) {
                        cost[i][j] = min(cost[i][j], cost[i - (1 << j)][l] + d[l][c[j]]);
                    }
                }
            }
        }
    }

    int res = inf;
    for (int i = 0; i < k; i++) {
        res = min(res, cost[(1 << k) - 1][i] + d[i][n]);
    }
    return res;
}

int main()
{
    f >> n >> m >> k;
    for (int i = 0; i < k; i++) {
        f >> c[i];
    }
    for (int i = 0; i < m; i++) {
        int x, y, z;
        f >> x >> y >> z;
        G[x].push_back(make_pair(y, z));
        G[y].push_back(make_pair(x, z));
    }

    dijkstra(1, src);
    if (k == 0) {
        g << src[n] << endl;
    } else {
        for (int i = 0; i < k; i++) {
            dijkstra(c[i], d[i]);
        }

        g << hamilton() << endl;
    }

    f.close();
    g.close();
    return 0;
}