Cod sursa(job #1509364)

Utilizator fanache99Constantin-Buliga Stefan fanache99 Data 23 octombrie 2015 19:25:00
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.09 kb
#include<cstdio>
#include<vector>
#include<set>
#define inf 2000000000
using namespace std;
int oras[20],n,m,k,drum[20][2010],dp[33000][20],cluj[2010];
vector<pair<int,int> > g[2010];
set<pair<int,int> > q;
int minim(int a,int b){
    if(a<b)
        return a;
    return b;
}
void dijkstra(int source,int best[2010]){
    int i,j,nod,cost;
    q.clear();
    for(i=1;i<=n;i++){
        best[i]=inf;
        if(i!=source)
            q.insert(make_pair(i,best[i]));
    }
    best[source]=0;
    q.insert(make_pair(source,0));
    while(!q.empty()){
        nod=q.begin()->first;
        cost=q.begin()->second;
        q.erase(q.begin());
        if(best[nod]<cost)
            continue;
        for(j=0;j<g[nod].size();j++)
            if(best[g[nod][j].first]>best[nod]+g[nod][j].second){
                best[g[nod][j].first]=best[nod]+g[nod][j].second;
                q.insert(make_pair(g[nod][j].first,best[g[nod][j].first]));
            }
    }
}
int main(){
    freopen("ubuntzei.in","r",stdin);
    freopen("ubuntzei.out","w",stdout);
    int i,j,h,a,b,c,cost,sol=inf;
    scanf("%d%d%d",&n,&m,&k);
    for(i=0;i<k;i++)
        scanf("%d",&oras[i]);
    for(i=1;i<=m;i++){
        scanf("%d%d%d",&a,&b,&c);
        g[a].push_back(make_pair(b,c));
        g[b].push_back(make_pair(a,c));
    }
    dijkstra(1,cluj);
    for(i=0;i<k;i++)
        dijkstra(oras[i],drum[i]);
    if(k==0){
        printf("%d",cluj[n]);
        return 0;
    }
    for(i=1;i<(1<<k);i++){
        j=0;
        while(j<k&&(i!=(1<<j)))
            j++;
        if(i==(1<<j)){
            dp[i][j]=cluj[oras[j]];
            continue;
        }
        for(j=0;j<k;j++){
            dp[i][j]=inf;
            if((i&(1<<j))>0)
                for(h=0;h<k;h++)
                    if(h!=j&&(((i&(1<<h))>0))){
                        cost=dp[i-(1<<j)][h]+drum[h][oras[j]];
                        dp[i][j]=minim(cost,dp[i][j]);
                    }
        }
    }
    for(i=0;i<k;i++)
        sol=minim(sol,dp[(1<<k)-1][i]+drum[i][n]);
    printf("%d",sol);
    return 0;
}