Cod sursa(job #2941264)

Utilizator Teodor94Teodor Plop Teodor94 Data 17 noiembrie 2022 15:21:12
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.3 kb
#include <bits/stdc++.h>
using namespace std;

#define INF 1e9

#define MAX_N 2000
#define MAX_K 15

struct Edge { int node, cost; };

struct BfNode { int node, visitedMask; };

int noNodes, noEdges;
vector<Edge> graph[MAX_N];

int noSpecialNodes;
int specialNodes[MAX_N];

int dist[MAX_K + 2][MAX_N];
int dp[MAX_K + 2][1 << (MAX_K + 2)];

void addSpecialNode(int x) {
    specialNodes[noSpecialNodes++] = x;
}

void addEdge(int x, int y, int c) {
    graph[x].push_back({y, c});
    graph[y].push_back({x, c});
}

void resetDist(int* dist) {
    int i;

    for (i = 0; i < noNodes; ++i)
        dist[i] = INF;
}

void bf(int node, int* dist) {
    queue<int> bfQueue;

    resetDist(dist);

    bfQueue.push(node);
    dist[node] = 0;

    while (!bfQueue.empty()) {
        node = bfQueue.front();
        bfQueue.pop();

        for (const Edge& edge : graph[node])
            if (dist[edge.node] > dist[node] + edge.cost) {
                dist[edge.node] = dist[node] + edge.cost;
                bfQueue.push(edge.node);
            }
    }
}

int main() {
    FILE *fin, *fout;
    fin = fopen("ubuntzei.in", "r");
    fout = fopen("ubuntzei.out", "w");

    int k, i, j, x, y, c, mask;

    fscanf(fin, "%d%d", &noNodes, &noEdges);
    fscanf(fin, "%d", &k);
    addSpecialNode(0);
    for (i = 0; i < k; ++i) {
        fscanf(fin, "%d", &x);
        addSpecialNode(x - 1);
    }
    addSpecialNode(noNodes - 1);
    for (i = 0; i < noEdges; ++i) {
        fscanf(fin, "%d%d%d", &x, &y, &c);
        addEdge(x - 1, y - 1, c);
    }

    for (i = 0; i < noSpecialNodes; ++i)
        bf(specialNodes[i], dist[i]);

    for (i = 0; i < noSpecialNodes; ++i)
        for (mask = 0; mask < (1 << noSpecialNodes); ++mask)
            dp[i][mask] = INF;

    dp[0][1 << 0] = 0;
    for (mask = 0; mask < (1 << noSpecialNodes); ++mask)
        for (i = 0; i < noSpecialNodes; ++i)
            if (mask & (1 << i))
                for (j = 0; j < noSpecialNodes; ++j)
                    if (i != j && (mask & (1 << j)))
                        dp[j][mask] = min(dp[j][mask], dp[i][mask - (1 << j)] + dist[i][specialNodes[j]]);

    fprintf(fout, "%d\n", dp[noSpecialNodes - 1][(1 << noSpecialNodes) - 1]);

    fclose(fin);
    fclose(fout);
    return 0;
}