Cod sursa(job #2246260)

Utilizator NicolaalexandraNicola Alexandra Mihaela Nicolaalexandra Data 26 septembrie 2018 21:13:10
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.45 kb
#include <fstream>
#include <vector>
#include <queue>
#include <bitset>
#define INF 2000000000
using namespace std;

ifstream fin ("ubuntzei.in");
ofstream fout ("ubuntzei.out");
int n,m,k,i,x,y,lg,nod,ii,j,t,s,vecin,cst;
int v[20],d[20][2001],dp[20][132000];
vector < pair<int,int> > L[2001],w[20];
priority_queue < pair<int,int> > h;
bitset <2001> f;
int main (){

    fin>>n>>m>>k;
    for (i=1;i<=k;i++)
        fin>>v[i];

    for (i=1;i<=m;i++){
        fin>>x>>y>>lg;
        L[x].push_back (make_pair(y,lg));
        L[y].push_back (make_pair(x,lg));
    }

    v[++k] = 1;
    v[++k] = n;
    /// construim un nou graf
    for (i=0;i<k;i++){
        f.reset();
        /// dijkstra
        nod = v[i+1];
        h.push (make_pair(0,nod));
        for (j=1;j<=n;j++){
            if (j != nod)
                h.push (make_pair(-INF,j));
            d[i][j] = INF;
        }
        d[i][nod] = 0;
        while (!h.empty()){
            nod = h.top().second;
            h.pop();
            while (f[nod]){
                if (h.empty()) break;
                nod = h.top().second;
                h.pop();
            }
            if (h.empty()) break;

            for (vector< pair<int,int> > :: iterator it=L[nod].begin();it!=L[nod].end();it++){
                vecin = it->first;
                cst = it->second;
                if (cst + d[i][nod] < d[i][vecin]){
                    d[i][vecin] = cst + d[i][nod];
                    h.push(make_pair(-d[i][vecin],vecin));
                }
            }
        }

        for (j=i+2;j<=k;j++){
            if (d[i][v[j]] != INF){
                w[i+1].push_back (make_pair(j,d[i][v[j]]));
                w[j].push_back (make_pair(i+1,d[i][v[j]]));
            }
        }

    }
    k-=2;
    /// dp[i][s] - drumul minim sa ajung in i si sa fi trecut
    /// cel putin odata prin starea s;

    for (i=1;i<=k;i++){
        for (j=0;j<=(1<<i)-1;j++)
            dp[i][j] = INF;
        dp[i][(1<<(i-1))] = d[i-1][1];
    }

    for (j=1;j<(1<<k);j++)
        for (i=1;i<=k;i++){
            if (dp[i][j] == INF)
                continue;
            for (t=1;t<=k;t++)
                if (t != i && (j & (1<<(t-1))) == 0 )
                    dp[t][j+(1<<(t-1))] = min (dp[t][j+(1<<(t-1))], dp[i][j] + d[i-1][v[t]] );
        }


    s = INF;
    for (i=1;i<=k;i++)
        s = min (s,dp[i][(1<<k)-1]+d[i-1][n] );
    fout<<s;

    return 0;
}