Cod sursa(job #3214817)

Utilizator NiffSniffCojocaru Calin Marcu NiffSniff Data 14 martie 2024 14:43:31
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.65 kb
#include <fstream>
#include <vector>
#include <queue>
#include <bitset>
using namespace std;
const int N = 2000, lim = 200000000;
string file = "ubuntzei";
ifstream cin (file + ".in");
ofstream cout (file + ".out");
int dp[65535][15]; // dp[i][j] = formatia i binara cu nodul curent j
struct muchie{
    int nod;
    int dist;
};
struct coada{
    int nod;
    int dist;
    inline bool operator < (const coada &y) const
    {
        return dist > y.dist;
    }
};
vector <muchie> L[N+1];
int loc[15],n,k;
int dist[N+1][N+1];

void dijkstra(int nod, int v[])
{
    for (int i=1; i<=n; i++)
    {
        v[i] = lim;
    }
    v[nod] = 0;
    priority_queue <coada> Q;
    Q.push({nod,0});
    while (!Q.empty())
    {
        nod = Q.top().nod;
        Q.pop();
        for (auto y : L[nod])
        {
            if (y.dist + v[nod] < v[y.nod])
            {
                v[y.nod] = y.dist + v[nod];
                Q.push({y.nod,v[y.nod]});
            }
        }
    }
}

void programare_dinamica()
{
    if (k==0)
    {
        cout << dist[1][n];
        return;
    }
    int N = (1<<k);
    for (int i=0; i<N; i++)
    {
        for (int j = 0; j<k; j++)
            dp[i][j] = lim;
    }
    for (int i=0; i<k; i++)
    {
        dp[(1<<i)][i] = dist[1][loc[i]];
    }
    for (int i=1; i<N; i++)
    {
        for (int j=0; j<k; j++)
        {
            if ((i & (1<<j)) != 0)
            {
                int l = (i^(1<<j));
                for (int t = 0; t<k; t++)
                {
                    dp[i][j] = min(dp[i][j], dp[l][t] + dist[loc[t]][loc[j]]);
                }
            }
        }
    }
    int c = lim;
    for (int j=0; j<k; j++)
    {
        c = min(c,dp[N-1][j] + dist[loc[j]][n]);
    }

    cout << c;
}

void afisari()
{
    cout << "1: ";
    for (int i=0; i<k; i++)
        cout << dist[1][loc[i]] << ' ';
    cout << endl;
    for (int i=0; i<k; i++)
    {
        cout << loc[i] << ": ";
        for (int j=0; j<k; j++)
            cout << dist[loc[i]][loc[j]] << ' ';
        cout << endl;
    }
    cout << "n: ";
    for (int i=0; i<k; i++)
        cout << dist[n][loc[i]] << ' ';
    cout << endl;
}
int main()
{
    int z;
    int x,y,m;
    cin >> n >> m >> k;
    for (int i=0; i<k; i++)
        cin >> loc[i];
    for (int i=1; i<=m; i++)
    {
        cin >> x >> y >> z;
        L[x].push_back({y,z});
        L[y].push_back({x,z});
    }
    dijkstra(1,dist[1]);
    dijkstra(n,dist[n]);
    for (int i=0; i<k; i++)
    {
        dijkstra(loc[i],dist[loc[i]]);
    }
    //afisari();
    programare_dinamica();
}