Cod sursa(job #1765501)

Utilizator SaitamaSaitama-san Saitama Data 26 septembrie 2016 19:53:11
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.92 kb
#include <bits/stdc++.h>
#define nmax 2005
#define kmax 33000
#define INF 2000000000

using namespace std;

ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");

struct muchie
{
    int nod, cost;
    bool operator < (const muchie &A) const
    {
        return cost > A.cost;
    }
};
priority_queue <muchie> q;
vector <muchie> L[nmax];
int a[20], cost[20][20];///costul de la al i-lea nod la j-lea nod (speciale)
int dij[nmax], sol;
int dp[kmax][20];///dp[stare][nod special];
int n, m, k;

void Read()
{
    int i, x, y, cost;
    muchie w;
    fin >> n >> m;
    fin >> k;
    for(i = 0; i < k; i++)
        fin >> a[i];
    for(i = 1; i <= m; i++)
    {
        fin >> x >> y >> cost;
        w.cost = cost;
        w.nod = y;
        L[x].push_back(w);
        w.nod = x;
        L[y].push_back(w);
    }
}

void Dijkstra(int nods)
{
    muchie w, w1;
    int j, c;
    w.nod = nods;
    w.cost = 0;
    q.push(w);
    while(!q.empty())
    {
        w = q.top();
        q.pop();
        for(unsigned i = 0; i < L[w.nod].size(); i++)
        {
            j = L[w.nod][i].nod;
            c = L[w.nod][i].cost;
            if(dij[j] > dij[w.nod] + c)
            {
                dij[j] = dij[w.nod] + c;
                w1.nod = j;
                w1.cost = dij[j];
                q.push(w1);
            }
        }
    }
}

void InitDinamica()
{
    int i, nod, stare;
    for(stare = 0; stare < (1 << k); ++stare)
        for(i = 0; i < k; i++) dp[stare][i] = INF;
    for(i = 1; i <= n; i++)
        dij[i] = INF;
    dij[1] = 0;
    Dijkstra(1);
    for(i = 0; i < k; i++)
    {
        nod = a[i];
        dp[1 << i][i] = dij[nod];
    }
}

void Solve()
{
    int i, j, nod;
    InitDinamica();
    ///Calculez distanta de la fiecare nod special la altul
    for(i = 0; i < k; i++)
    {
        nod = a[i];
        for(j = 1; j <= n; j++)
            dij[j] = INF;
        dij[nod] = 0;
        Dijkstra(nod);
        for(j = 0; j < k; j++)
            cost[i][j] = dij[a[j]];
    }
    ///Pentru fiecare stare
    int stare, smax;
    smax = (1 << k);
    for(stare = 0; stare <= smax; stare++)
        for(i = 0; i < k; i++)
            if((stare & (1 << i)))
                for(j = 0; j < k; j++)///Aleg urmatorul nod special unde sa ma duc
                    if(!(stare & (1 << j)))///Daca nu am mai fost
                        dp[stare | (1 << j)][i]///Actualizez
                            = min( dp[stare | (1 << j)][i],
                                   dp[stare][i] + cost[i][j]);
    ///Calculam distanta de la nodul N la fiecare nod special
    for(i = 1; i <= n; i++)
        dij[i] = INF;
    dij[n] = 0;
    Dijkstra(n);
    sol = INF;
    for(i = 0; i < k; i++)
        sol = min(sol, dp[smax - 1][i] + dij[a[i]]);
    fout << sol;
}

int main()
{
    Read();
    Solve();
    fin.close();fout.close();
    return 0;
}