Cod sursa(job #1725577)

Utilizator dani_mocanuDani Mocanu dani_mocanu Data 5 iulie 2016 22:35:32
Problema Ubuntzei Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.31 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
int N,M,K;
const int INF = 2000000000;
const int kmax = (1 << 15) + 3;
const int nmax = 2005;
int a[20],cost[20][20],dp[kmax][17],D[nmax],ans;
vector < int > G[nmax];
vector < int > L[nmax];
struct el
{
    int nod,cost;
    bool operator < (const el &A) const
    {
        return cost > A.cost;
    }
};
priority_queue <el> Q;
inline void Read()
{
    int i,x,y,z;
    fin >> N >> M >> K;
    for(i = 1; i <= K; i++) fin >> a[i];
    a[0] = 1, a[++K] = N;
    for(i = 1; i <= M; i++)
    {
        fin >> x >> y >> z;
        G[x].push_back(y);
        L[x].push_back(z);
        G[y].push_back(x);
        L[y].push_back(z);
    }
}

inline void Dijkstra()
{
    el E,W;
    int nod,nnod,ccost;
    while(!Q.empty())
    {
        E = Q.top();
        Q.pop();
        nod = E.nod;
        for(unsigned int i = 0; i < G[nod].size(); i++)
        {
            nnod = G[nod][i];
            ccost = L[nod][i];
            if(D[nnod] > D[nod] + ccost)
            {
                D[nnod] = D[nod] + ccost;
                W.nod = nnod;
                W.cost = D[nnod];
                Q.push(W);
            }
        }
    }
}

inline void Build()
{
    int i,j;
    el E;
    for(i = 0; i <= K; i++)
    {
        for(j = 1; j <= N; j++) D[j] = INF;
        D[a[i]] = 0;
        E.nod = a[i];
        E.cost = 0;
        Q.push(E);
        Dijkstra();
        for(j = 0; j <= K; j++) cost[i][j] = D[a[j]];
    }
}

inline void Solve()
{
    int  i,stare,j,KPOW,k;
    ans = INF;
    K++;
    KPOW = (1 << K);
      for(stare = 1; stare < KPOW; ++stare)
        for(j = 0; j <= K; j++) dp[stare][j] = INF;
    for(i = 0; i <= K; i++) dp[1 << i][i] = cost[0][i];
    for(stare = 1; stare < KPOW; ++stare)
        for(i = 0; i <= K; i++)
            if((stare & (1 << i)))
                for(j = 0; j <= K; j++)
                    if(!(stare & (1 << j)))
                        dp[stare | (1 << j)][j] = min(dp[stare | (1 << j)][j],dp[stare][i] + cost[i][j]);
    for(i = 0; i < K; i++)
        ans = min(ans, dp[KPOW - 1][i] + cost[i][K]);
    fout << ans << "\n";
    fout.close();
}

int main()
{
    Read();
    Build();
    Solve();
    return 0;
}