Cod sursa(job #838187)

Utilizator Theorytheo .c Theory Data 19 decembrie 2012 02:09:45
Problema Ubuntzei Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.28 kb
#include<fstream>
#include<queue>
#include<vector>
#define inf 10000000
#define nmax 2007
#define mmax 10009
using namespace std;

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

int N, M, K;
int dist[20][20];
int drum[1 << 16][16];

struct Nod{
    int x, cost;
    Nod(int _x,int _cost){
        x = _x;
        cost = _cost;
    }
    Nod(){
        x = 0; cost = 0;
    }
    bool operator <(const Nod f)const{
        return f.cost > cost;
    }
};
int d[nmax];
vector <Nod> G[nmax];
vector <int> S;

void read(){
    fin >>N>>M>>K;

    for(int i = 1; i <= K; i++){
        int x;
        fin >>x;
        --x;
        S.push_back(x);
    }
    S.push_back(N - 1);
    S.push_back(0);
    K +=2;
    for(int i = 1; i <= M; i++){
        int x, y, cost;


        fin >>x >>y >> cost;
        --x;
        --y;
        G[x].push_back(Nod(y,cost));
        G[y].push_back(Nod(x,cost));

    }

}
void Dijkstra(int x, int d[]){
    for(int i = 0; i<= N; i++)
        d[i] = inf;
    d[x] = 0;
    priority_queue <Nod> H;
    H.push(Nod(x,0));
    while( ! H.empty() ){
        int nod = H.top().x;
        H.pop();
        for(vector <Nod>::iterator it = G[nod].begin(); it != G[nod].end(); it++){
            int y = it -> x;
            int Cost = it -> cost;
            if(d[y] > d[nod] + Cost){
                d[y] = d[nod] + Cost;
                H.push(Nod(y, Cost));
            }

        }
    }

}
void solve(){
    for(int i = 0 ;i < K; i++){
        Dijkstra(S[i],d);
        for(int j = 0 ;j < K; j++)
            dist[i][j] = d[S[j]];

    }
    for(int i = 0 ;i < (1<< ( K - 1)); i++)
        for(int j = 0 ;j < K; j++)
            drum[i][j] =inf;

    for(int i = 0; i < K; i++)
        drum[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(drum[i][j] != inf)
                for(int t = 0 ;t < K - 1; t++){
                    if( (1 << t) & (~i))
                    drum[ i | (1<<t)][t] = min (drum[i | (1<<t)][t] , drum[i][j] + dist[j][t]);
                }

        }

    fout << drum [ (1 << (K - 1) ) - 1][K - 2];
}
int main(){
    read();
    solve();
    fin.close();
    return 0;
}