Cod sursa(job #977806)

Utilizator CosminRusuCosmin Rusu CosminRusu Data 26 iulie 2013 17:45:24
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.96 kb
#include <fstream>
#include <vector>
#include <bitset>
#include <queue>
#include <algorithm>
#include <utility>
#include <string.h>

using namespace std;

ifstream cin("ubuntzei.in");
ofstream cout("ubuntzei.out");

const int MAXN = 2005;
const int MAXK = 17;
const int oo = 0x3f3f3f3f;

typedef vector< pair<int, int> > Graph[MAXN];
typedef vector< pair<int, int> > :: iterator It;

Graph G;
int N, M, K, U[MAXK], D[MAXK][MAXN], dp[1<<MAXK][MAXK];
vector<int>d(MAXN);
priority_queue <pair<int, int> , vector<pair<int, int> > , greater<pair<int, int> > > Q;

inline void Dijkstra(int Source) {
    for(Q.push(make_pair(0, Source)), d[Source] = 0; !Q.empty() ; Q.pop()) {
        int Node = Q.top().second;
        for(It it = G[Node].begin(), fin = G[Node].end() ; it != fin ; ++ it)
            if(d[it->first] > d[Node] + it->second)
                d[it->first] = d[Node] + it->second, Q.push(make_pair(d[it->first], it->first));
    }
}
int main(){
    cin >> N >> M >> K;
    for(int i = 1 ; i <= K ; ++ i)
        cin >> U[i];
    U[++K] = N;
    for(int i = 1 ; i <= M ; ++ i){
        int X, Y, Cost;
        cin >> X >> Y >> Cost;
        G[X].push_back(make_pair(Y, Cost));
        G[Y].push_back(make_pair(X, Cost));
    }
    for(int i = 1 ; i <= K ; ++ i){
        fill(d.begin(), d.end(), oo);
        Dijkstra(U[i]);
        for(int j = 1 ; j <= N ; ++ j)
            D[i][j] = d[j];
    }
    fill(d.begin(), d.end(), oo);
    Dijkstra(1);
    memset(dp, oo, sizeof(dp));
    for(int i = 1, j = 0; i < (1 << K); i *= 2, ++j)   dp[i][j] = d[U[j+1]];
    for(int i = 1 ; i < (1 << K) ; ++ i)
        for(int j = 0 ; j < K ; ++ j)
            if(i & (1<<j))
                for(int k = 0; k < K; ++k)
                    if(i & (1 << k) && k != j)
                        dp[i][j] = min(dp[i][j], dp[i^(1 << j)][k] + D[k+1][U[j+1]]);

    cout << dp[(1<<K)- 1][K-1] <<"\n";
    cin.close();
    cout.close();
    return 0;
}