Cod sursa(job #2941257)

Utilizator Teodor94Teodor Plop Teodor94 Data 17 noiembrie 2022 14:07:10
Problema Ubuntzei Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.13 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, cost; };

inline bool operator<(const BfNode& node1, const BfNode& node2) {
    return node1.cost > node2.cost;
}

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

int noSpecialNodes;
int isSpecialNode[MAX_N];

int dist[MAX_N][1 << MAX_K];

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

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

void resetDist() {
    int i, mask;

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

void dijkstra(BfNode node) {
    priority_queue<BfNode> dijkstraHeap;
    int visitedMask;

    resetDist();

    dijkstraHeap.push(node);
    dist[node.node][node.visitedMask] = 0;

    while (!dijkstraHeap.empty()) {
        node = dijkstraHeap.top();
        dijkstraHeap.pop();

        for (const Edge& edge : graph[node.node]) {
            visitedMask = node.visitedMask;
            if (isSpecialNode[edge.node])
                visitedMask |= 1 << (isSpecialNode[edge.node] - 1);

            if (dist[edge.node][visitedMask] > node.cost + edge.cost) {
                dist[edge.node][visitedMask] = node.cost + edge.cost;
                dijkstraHeap.push({edge.node, visitedMask, node.cost + edge.cost});
            }
        }
    }
}

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

    int k, i, x, y, c;

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

    dijkstra({0, 0, 0});

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

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