Cod sursa(job #838248)

Utilizator Theorytheo .c Theory Data 19 decembrie 2012 10:30:40
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.32 kb
#include<fstream>
#include<set>
#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 <pair<int,int> > 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(make_pair(cost,y));
        G[y].push_back(make_pair(cost,x));

    }

}
void Dijkstra(int x, int d[]){
    set<pair<int,int> >s;
    s.insert(make_pair(0,x));
    for(int i = 0; i<= N; i++)
        d[i] = inf;
    d[x] = 0;

    while( ! s.empty() ){
        int nod = (*s.begin()).second;
        s.erase(s.begin());
        for(int i = 0 ; i < G[x].size(); i++){
            if(d[G[x][i].second] > d[nod] + G[x][i].second){
                d[G[x][i].second] = d[nod] + G[x][i].second;

                s.insert(make_pair(G[x][i].first,G[x][i].second));

            }

        }
    }

}
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;
}