Cod sursa(job #1775289)

Utilizator DobosDobos Paul Dobos Data 10 octombrie 2016 10:19:42
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.6 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin ("ubuntzei.in");
ofstream fout ("ubuntzei.out");
const int NMAX = 2005;
const int KMAX = 17;
const int BMOD = 5000;
const int INF = 1e9;
char buffer[BMOD + 1];
int e = BMOD - 1,D[KMAX][NMAX],n,S,C[NMAX],SOL[(1 << KMAX)][KMAX];
vector < pair < int,int > > G[NMAX];
struct cmp{
    bool operator()(const int &a,const int &b){
        return D[S][a] > D[S][b];
    }
};
priority_queue < int , vector < int > , cmp > T;
inline void parsare(int &x)
{
    while(!isdigit(buffer[e])){
        e++;
        if(e == BMOD)
            e = 0,fin.read(buffer,BMOD);
    }
    x = 0;
    while(isdigit(buffer[e])){
        x = x * 10 + (buffer[e] - '0');
        e++;
        if(e == BMOD)
            e = 0,fin.read(buffer,BMOD);
    }
}
inline int bit(int x,int y){
return (x & (1 << y)) != 0;
}
inline void dijkstra(int nod,int *V)
{
    for(int i = 1; i <= n; i++)
        V[i] = INF;
    V[nod] = 0;
    for(int i = 1; i <= n; i++)
        T.push(i);
    while(!T.empty())
    {
        nod = T.top();
        T.pop();
        for(int  i = 0 ; i < G[nod].size(); i ++){
            if(V[G[nod][i].second] > V[nod] + G[nod][i].first){
                V[G[nod][i].second] = V[nod] + G[nod][i].first;
                T.push(G[nod][i].second);
            }
        }
    }
}
int main()
{
    int m,x,y,c,K,newdis;
    parsare(n); parsare(m); parsare(K);
    for(int i = 0; i < K ; i++)
        parsare(C[i]);
    for(int i = 1; i <= m; i++){
        parsare(x); parsare(y); parsare(c);
        G[x].push_back({c,y});
        G[y].push_back({c,x});
    }
    S = KMAX  - 1;
    dijkstra(1,D[S]);
    if(K == 0){
        fout << D[KMAX - 1][n];
        return 0;
    }
    for(int i = 0 ; i < K; i++){
        S = i;
        dijkstra(C[i],D[i]);
    }
    int j;
    for(int i  = 1; i  < (1 << K); i++){
        for( j  = 0 ; j < K; j++){
            if(i == (1<<j))
                break;
        }
        if( j < K && i == (1<<j)){
            SOL[i][j] = D[KMAX - 1][C[j]];
            continue;
        }
        for(j = 0; j < K; j++){
            SOL[i][j] = INF;
            if(bit(i,j)){
                for(int k = 0; k < K; k++){
                    if(bit(i,k) && j != k){
                        newdis = SOL[i - (1<<j)][k] + D[k][C[j]];
                        SOL[i][j] = min(SOL[i][j] , newdis);
                    }
                }
            }
        }
    }
    S = INF;
    for(int i  = 0 ; i < K; i++){
        S = min(S,SOL[(1 << K)-1][i] + D[i][n]);
    }
    fout << S;
    return 0;
}