Cod sursa(job #1328456)

Utilizator ooptNemes Alin oopt Data 28 ianuarie 2015 13:31:04
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.47 kb
/// ubuntzei
#include <iostream>
#include <fstream>
#include <set>
#include <algorithm>
#include <vector>

#define NMax 2005
#define KMax 16
#define mp make_pair
#define pb push_back
#define inf (1<<30)+100

using namespace std;

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

inline int minim(int a, int b) { return ((a<b)?(a):(b)); };
inline int maxim(int a, int b) { return ((a>b)?(a):(b)); };

int n,m;
int joints = 0;
int distTmp[NMax];
vector<int> V[NMax];
vector<int> C[NMax];
int dist[KMax+3][KMax+3];
int J[KMax+3];
int DP[1<<KMax][KMax];
set< pair<int, int> > S; /// Set for dijkstra

void dijkstra(int node) {
    S.erase(S.begin(), S.end());
    for (int i=1;i<=n;i++)
        distTmp[i] = inf;
    distTmp[node] = 0;

    S.insert(mp(node, 0));
    while (!S.empty()) {
        int nod = (*(S.begin())).first, cost = (*(S.begin())).second;
        S.erase(S.begin());

        for (unsigned i=0;i<V[nod].size();i++) {
            int vecin = V[nod][i];
            if (distTmp[vecin] > cost + C[nod][i]) {
                distTmp[vecin] = cost + C[nod][i];
                S.insert(mp(vecin, distTmp[vecin]));
            }
        }
    }
}

void read() {
    f>>n>>m;
    f>>joints;
    for (int i=1;i<=joints;i++)
        f>>J[i];
    for (int i=1;i<=m;i++) {
        int x, y, c;
        f>>x>>y>>c;
        V[x].push_back(y);
        C[x].push_back(c);
        V[y].push_back(x);
        C[y].push_back(c);
    }
}

void solve() {
    if (joints == 0) {
        dijkstra(1);
        g<<distTmp[n]<<'\n';
        return;
    }

    J[0] = 1;
    for (int i=0;i<=joints;i++) {
        dijkstra(J[i]);
        for (int j=0;j<=joints;j++)
            dist[i][j] = distTmp[J[j]];
        dist[i][joints+1] = distTmp[n];
    }

    int lim = 1<<joints;
    for (int i=0;i<lim;i++) {
        for (int j=0;j<=joints;j++)
            DP[i][j] = inf;
    }
    DP[0][0] = 0;

    for (int i=1;i<lim;i++) {
        for (int j=0;j<joints;j++) {
            if (i & (1<<j)) {
                int mask2 = i-(1<<j);
                for (int p=0;p<=joints;p++) {
                    DP[i][j+1] = minim(DP[i][j+1], DP[mask2][p] + dist[p][j+1]);
                }
            }
        }
    }

    int sol = inf;
    for (int i=1;i<=joints;i++)
        sol = minim(sol, DP[lim-1][i] + dist[i][joints+1]);
    g<<sol<<'\n';
}

int main() {

    read();
    solve();

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