Cod sursa(job #1133549)

Utilizator teoionescuIonescu Teodor teoionescu Data 4 martie 2014 23:39:38
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.38 kb
#include<fstream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<string>
#include<queue>
#define abs(x) ((x>0)?(x):(-(x)))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define ll long long
using namespace std;
ifstream in("ubuntzei.in");
ofstream out("ubuntzei.out");
const int Nmax = 2005;
const int Ubmax = 18;
const int INF = 1<<30;
vector<int> G[Nmax],C[Nmax];
int N,M,K;
int U[Ubmax];
int Cost[Ubmax][Ubmax];
int Last[Ubmax];
int Dp[(1<<Ubmax)][Ubmax];
struct hitem{
    int to,cost;
    hitem(){}
    hitem(int _x,int _y){
        to=_x;
        cost=_y;
    }
};
struct cmp{
    inline bool operator()(const hitem a,const hitem b){
        return a.cost>b.cost;
    }
};
priority_queue<hitem,vector<hitem>,cmp> q;
int D[Nmax];
void Dijk(int sursa){
    for(int i=1;i<=N;i++) D[i]=INF;
    D[sursa]=0;
    q.push(hitem(sursa,0));
    while(!q.empty()){
        hitem p=q.top();
        q.pop();
        for(int i=0;i<G[p.to].size();i++){
            if( p.cost+C[p.to][i] < D[ G[p.to][i] ] ){
                D[ G[p.to][i] ] = p.cost+C[p.to][i];
                q.push(hitem(G[p.to][i],D[ G[p.to][i] ]));
            }
        }
    }
}
int main(){
    in>>N>>M>>K;
    for(int i=1;i<=K;i++) in>>U[i];
    for(int i=1;i<=M;i++){
        int x,y,c;
        in>>x>>y>>c;
        G[x].push_back(y);
        C[x].push_back(c);
        G[y].push_back(x);
        C[y].push_back(c);
    }
    U[0]=1;
    for(int i=0;i<=K;i++){
        Dijk(U[i]);
        for(int j=0;j<=K;j++){
            if(i==j) Cost[i][j]=0;
            else{
                Cost[i][j]=( D[U[j]]==INF ? 0 : D[U[j]] );
            }
        }
        Last[i]=( D[N]==INF ? 0 : D[N] );
    }
    K++;
    for(int i=0;i<=(1<<K)-1;i++){
        for(int j=0;j<K;j++){
            Dp[i][j]=INF;
        }
    }
    Dp[1][0]=0;
    for(int i=0;i<=(1<<K)-1;i++){
        for(int j=0;j<K;j++){
            if(i&(1<<j)){
                for(int k=0;k<K;k++){
                    if(i&(1<<k) && Cost[k][j]){
                        Dp[i][j]=min(Dp[i][j],Dp[i^(1<<j)][k] + Cost[k][j]);
                    }
                }
            }
        }
    }
    int Ans=INF;
    for(int j=0;j<K;j++){
        if(Last[j]){
            Ans=min(Ans,( Dp[(1<<K)-1][j] + Last[j] ));
        }
    }
    out<<Ans<<'\n';
    return 0;
}