Cod sursa(job #2473694)

Utilizator Ionut28Porumb Palincas Ionut Ionut28 Data 14 octombrie 2019 06:35:29
Problema Ubuntzei Scor 100
Compilator cpp-64 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");
const int nmax = 2005;
const int oo = 2e9;
const int kmax = (1 << 17) + 3;
int v[20], cost[20][20], dp[kmax][20], D[nmax], ans, n, m, k;
vector < int > L[nmax], G[nmax];
struct el
{
    int nod, cost;
    bool operator < (const el &A) const
    {
        return cost > A.cost;
    }
};
priority_queue < el > Q;
void read()
{
    fin >> n >> m;
    fin >> k;
    for(int i = 1; i <= k; ++i)
        fin >> v[i];
    v[0] = 1, v[++k] = n;
    for(int i = 1; i <= m; ++i)
    {
        int x, y, z;
        fin >> x >> y >> z;
        G[x].push_back(y), G[y].push_back(x);
        L[x].push_back(z), L[y].push_back(z);
    }
}
void dijkstra()
{
    el w, W;
    int nod, vecin, ccost;
    while(!Q.empty())
    {
        w = Q.top();
        Q.pop();
        nod = w.nod;
        for(unsigned int i = 0; i < G[nod].size(); ++i)
        {
            vecin = G[nod][i];
            ccost = L[nod][i];
            if(D[vecin] > D[nod] + ccost)
            {
                D[vecin] = D[nod] + ccost;
                W.nod = vecin;
                W.cost = D[vecin];
                Q.push(W);
            }
        }
    }
}
void build()
{
    el E;
    for(int i = 0; i <= k; ++i)
    {
        for(int j = 1; j <= n; ++j)
            D[j] = oo;
        D[v[i]] = 0;
        E.nod = v[i];
        E.cost = 0;
        Q.push(E);
        dijkstra();
        for(int j = 0; j <= k; ++j)
            cost[i][j] = D[v[j]];
    }
}
void solve()
{
    int stare, kpow;
    ans = oo;
    kpow = (1 << k);
    for(stare = 1; stare < kpow; ++stare)
        for(int j = 0; j <= k; ++j)
            dp[stare][j] = oo;
    for(int i = 0; i <= k; ++i)
        dp[1 << i][i] = cost[0][i];
    for(stare = 1; stare < kpow; ++stare)
        for(int i = 0; i <= k; ++i)
            if((stare & (1 << i)))
                for(int 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(int i = 0; i <= k; ++i)
        ans = min(ans, dp[kpow - 1][i] + cost[i][k]);
    fout << ans << "\n";
}
int main()
{
    read();
    build();
    solve();
    return 0;
}