Cod sursa(job #3359751)

Utilizator daviddxmqStan David Andrei daviddxmq Data 3 iulie 2026 15:30:24
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.95 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

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

const int MAXN = 2005;
const int INF = 1e9;

vector<int> g[MAXN];
int lungime_directa[MAXN][MAXN];
int dist[MAXN][MAXN];
bool vizitat[MAXN];

int n, m, k;
int localitati[20];
int stari_traseu[1 << 15][20];

void gasireLungime(int start) {
    for (int i = 1; i <= n; ++i) {
        dist[start][i] = INF;
        vizitat[i] = false;
    }

    dist[start][start] = 0;

    for (int pas = 1; pas <= n; ++pas) {
        int nod_minim = -1;
        int min_dist = INF;

        for (int i = 1; i <= n; ++i)
            if (!vizitat[i] && dist[start][i] < min_dist) {
                min_dist = dist[start][i];
                nod_minim = i;
            }

        if (nod_minim == -1) break;

        vizitat[nod_minim] = true;

        for (int i = 0; i < g[nod_minim].size(); ++i) {
            int vecin = g[nod_minim][i];
            int cost_sosea = lungime_directa[nod_minim][vecin];

            if (dist[start][nod_minim] + cost_sosea < dist[start][vecin])
                dist[start][vecin] = dist[start][nod_minim] + cost_sosea;
        }
    }
}

int main() {
    in >> n >> m >> k;

    for (int i = 0; i < k; ++i)
        in >> localitati[i];

    for (int i = 0; i < m; ++i) {
        int x, y, z;
        in >> x >> y >> z;
        g[x].push_back(y);
        g[y].push_back(x);
        lungime_directa[x][y] = lungime_directa[y][x] = z;
    }

    gasireLungime(1);
    gasireLungime(n);
    for (int i = 0; i < k; ++i)
        gasireLungime(localitati[i]);

    if (k == 0) {
        out << dist[1][n] << "\n";
        return 0;
    }

    for (int configuratie = 0; configuratie < (1 << k); ++configuratie)
        for (int i = 0; i < k; ++i)
            stari_traseu[configuratie][i] = INF;

    for (int i = 0; i < k; ++i)
        stari_traseu[1 << i][i] = dist[1][localitati[i]];

    for (int configuratie = 1; configuratie < (1 << k); ++configuratie)
        for (int i = 0; i < k; ++i)
            if (stari_traseu[configuratie][i] != INF)
                for (int j = 0; j < k; ++j)
                    if ((configuratie & (1 << j)) == 0) {
                        int urmatoarea_configuratie = configuratie | (1 << j);
                        if (stari_traseu[configuratie][i] + dist[localitati[i]][localitati[j]] < stari_traseu[urmatoarea_configuratie][j])
                            stari_traseu[urmatoarea_configuratie][j] = stari_traseu[configuratie][i] + dist[localitati[i]][localitati[j]];
                    }

    int raspuns_minim = INF;
    int configuratie_plina = (1 << k) - 1;

    for (int i = 0; i < k; ++i)
        if (stari_traseu[configuratie_plina][i] + dist[localitati[i]][n] < raspuns_minim)
            raspuns_minim = stari_traseu[configuratie_plina][i] + dist[localitati[i]][n];

    out << raspuns_minim << "\n";

    return 0;
}