Cod sursa(job #901132)

Utilizator deneoAdrian Craciun deneo Data 1 martie 2013 00:54:26
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.26 kb
#include <queue>
#include <vector>
#include <fstream>
#include <algorithm>
#include <cstring>
using namespace std;

ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");

#define MAXN 2100
#define MAXK 16
#define mp make_pair
#define inf 0x3f3f3f3f

int N, K, M, dist[MAXN][MAXN], pd[1 << MAXK][MAXK], viz[MAXN];
vector<int> nodes;
vector<pair<int, int> > g[MAXN];

struct comp {
    bool operator() (const pair<int, int> &a, const pair<int, int> &b) const {
        return a.first > b.first;
    }
};

void dijkstra(int nod, vector<int> &di) {
    priority_queue <pair<int, int>, vector<pair<int, int> >, comp> s;
    s.push(mp(0, nod));
    di.resize(N, inf);
    di[nod] = 0;
    memset(viz, 0, sizeof(viz));

    while (!s.empty()) {
        int nodulet = s.top().second;
        s.pop();
        if (!viz[nodulet])
            for (int i = 0; i < g[nodulet].size(); ++i) {
                if (di[g[nodulet][i].first] > di[nodulet] + g[nodulet][i].second) {
                    di[g[nodulet][i].first] = di[nodulet] + g[nodulet][i].second;
                    s.push(mp(di[g[nodulet][i].first], g[nodulet][i].first));
                }
            }
        viz[nodulet] = 1;
    }
}

int main() {
    fin >> N >> M >> K;

    for (int i = 1; i <= K; ++i) {
        int x;
        fin >> x; --x;
        nodes.push_back(x);
    }

    nodes.push_back(N - 1);
    nodes.push_back(0);
    K += 2;

    for (int i = 1; i <= M; ++i) {
        int x, y, z;
        fin >> x >> y >> z; --x; --y;
        g[x].push_back(mp(y, z));
        g[y].push_back(mp(x, z));
    }

    for (int i = 0; i < K; ++i) {
        vector<int> di;
        dijkstra(nodes[i], di);
        for (int j = 0; j < K; ++j)
            dist[i][j] = di[nodes[j]];
    }

    memset(pd, inf, sizeof(pd));

    for (int i = 0; i < K - 1; ++i)
        pd[1 << i][i] = dist[K - 1][i];

    for (int i = 0; i < (1 << (K - 1)); ++i)
        for (int j = 0; j < K - 1; ++j)
            if (pd[i][j] != inf)
                for (int t = 0; t < K - 1; ++t)
                    if ((1 << t) & (~i))
                        pd[i | (1 << t)][t] = min(pd[i | (1 << t)][t], pd[i][j] + dist[j][t]);

    fout << pd[(1 << (K - 1)) - 1][K - 2];
    return 0;

}