Cod sursa(job #868957)

Utilizator razvan.popaPopa Razvan razvan.popa Data 31 ianuarie 2013 20:14:30
Problema Ubuntzei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.42 kb
#include<iostream>
#include<iostream>
#include<fstream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iomanip>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<bitset>
#include<algorithm>
#define INF (1 << 30)
#define pb push_back
#define mkp make_pair
#define pii pair<int, int>
#define ll long long
#define nxt (*it).first
#define cst (*it).second
#define type pii
#define FORi(i,a,b)\
   for(int i=a; i<b; ++i)
#define FORir(i,a,b)\
   for(int i=a; i>=b; --i)
#define FORr(g)\
   for(vector<type>::reverse_iterator it=g.rbegin(); it!=g.rend(); ++it)
#define FOR(g)\
   for(vector<type>::iterator it=g.begin(); it!=g.end(); ++it)
#define infile "ubuntzei.in"
#define outfile "ubuntzei.out"
#define nMax 2005
#define kMax 15
using namespace std;

vector < type > v[nMax];

priority_queue < type > PQ;

int Dist[kMax][nMax], source[nMax];

int L[kMax], DP[1<<kMax][kMax];

int N, M, K, Sol = INF;

void read(){
    ifstream f(infile);

    f >> N >> M >> K;

    FORi(i,0,K)
       f >> L[i];

    int x, y, cost;
    while(M--){
        f >> x >> y >> cost;

        v[x].pb(mkp(y,cost));
        v[y].pb(mkp(x,cost));
    }

    f.close();
}


void dijkstra(int src, int *Dist){
    fill(Dist, Dist+N+1, INF);
    Dist[src] = 0;
    PQ.push(mkp(-0, src));

    while(!PQ.empty()){
        int cost = -PQ.top().first;
        int  x   = PQ.top().second;
        PQ.pop();

        if(cost > Dist[x])
           continue;

        FOR(v[x])
           if(Dist[nxt] > Dist[x] + cst){
               Dist[nxt] = Dist[x] + cst;
               PQ.push(mkp(-Dist[nxt], nxt));
           }
    }
}

void solve(){
    dijkstra(1, source);
    if(!K){
        Sol = source[N];
        return;
    }

    FORi(i,0,K)
       dijkstra(L[i], Dist[i]);

    FORi(i,0,1<<K)
        FORi(j,0,K)
           if(i & (1<<j)){
               if(i == 1<<j){
                  DP[i][j] = source[L[j]];
                  break;
               }

               DP[i][j] = INF;
               FORi(k,0,K)
                  if(k != j && i & (1<<k))
                      DP[i][j] = min(DP[i][j], DP[i^(1<<j)][k] + Dist[k][L[j]]);

               break;
           }

    FORi(i,0,K)
       Sol = min(Sol, DP[(1<<K) - 1][i] + Dist[i][N]);
}

void print(){
    ofstream g(outfile);

    g << Sol <<'\n';

    g.close();
}

int main(){
    read();
    solve();
    print();

    return 0;
}