Cod sursa(job #2999698)

Utilizator TUDORBRKTudor Berechet TUDORBRK Data 11 martie 2023 12:21:19
Problema Ubuntzei Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.08 kb
#include <bits/stdc++.h>
#define INTMAX 1000000

using namespace std;
ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");

int n, m, k;
int v[16], a[2001][2001];
bool sptSet[2001];

int minDist(int dist[2001])
{
    int mini = INTMAX, nodMin = 0;
    for(int i = 1; i <= n; i++)
    {
        if(sptSet[i] == false && mini > dist[i])
            mini = dist[i], nodMin = i;
    }

    return nodMin;
}

void dijkstra(int start, int dist[2001])
{
    for(int i = 1; i <= n; i++)
        dist[i] = INTMAX, sptSet[i] = false;

    dist[start] = 0;

    for(int contor = 1; contor < n; contor++)
    {
        int curent = minDist(dist);
        sptSet[curent] = true;

        for(int i = 1; i <= n; i++)
        {
            if(a[i][curent] && sptSet[i] == false && dist[i] > dist[curent] + a[i][curent])
                dist[i] = dist[curent] + a[i][curent];
        }
    }
}

int main()
{
    f>>n>>m;

    f>>k;
    for(int i = 0; i < k; i++)
        f>>v[i];

    for(int i = 1; i <= m; i++)
    {
        int x, y, d;
        f>>x>>y>>d;
        a[x][y] = a[y][x] = d;
    }

    int path[2001];
    dijkstra(1, path);

    int drum[16][2001], dp[1 << k][k];
    for(int i = 0; i < k; i++)
        dijkstra(v[i], drum[i]);

    for(int i = 1; i < 1 << k; i++)
    {
        int j;
        for(j = 0; j < k; j++)
            if(i == 1 << j)
                break;

        if(1 << j == i && j < k)
        {
            dp[i][j] = path[v[j]];

            continue;
        }

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

    int mini = INTMAX;
    for(int i = 0; i < k; i++)
    {
        mini = min(mini, dp[(1 << k) - 1][i] + drum[i][n]);
    }

    g<<mini;
}