Cod sursa(job #2176189)

Utilizator savigunFeleaga Dragos-George savigun Data 16 martie 2018 21:27:06
Problema Ubuntzei Scor 45
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.02 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

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

typedef long long LL;

struct Edge { int y, dist; };
struct Node { int x, dist; int viz; };

const int INF = 2e13 + 1;
const int MAXN = 2005;
int n, m, k;
int dist[MAXN][32768];
int bit[MAXN]; // 0 daca nu sunt prieteni acolo sau indexul bitului corespunzator nodului, daca sunt prieteni
int viz[MAXN];
vector<Edge> g[MAXN];

class Cmp {
public:
    bool operator()(Node a, Node b) {
        return a.dist > b.dist;
    }
};

bool other_friends(int a, int b) {
    for (int i = 0; i < k; ++i) {
        int bitA = a & 1;
        int bitB = b & 1;
        if (bitA == 1 && bitB == 0) return true;
        a /= 2;
        b /= 2;
    }
    return false;
}

void Dijkstra() {
    priority_queue<Node, vector<Node>, Cmp> q;
    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j <= 1 << k; ++j) dist[i][j] = INF;
    }
    dist[1][0] = 0;
    q.push({1, 0, 0});

    int k_mask = (1 << k) - 1;

    while (!q.empty()) {
        Node now = q.top(); q.pop();
        int x = now.x;
        dist[x][now.viz] = now.dist;

        if (x == n && now.viz == k_mask) {
            out << dist[x][k_mask];
            return;
        }

        for (Edge &e : g[x]) {
            int y = e.y;
            if (dist[x][now.viz] + e.dist < dist[y][now.viz]) {
                int viz = now.viz;
                if (bit[y] != -1) viz |= (1 << bit[y]);
                dist[y][viz] = dist[x][now.viz] + e.dist;
                q.push({y, dist[y][viz], viz});
            }
        }
    }
}

int main()
{
    in >> n >> m >> k;
    for (int i = 1; i <= n; ++i) bit[i] = -1;
    for (int i = 0, x; i < k; ++i) {
        in >> x;
        bit[x] = i;
    }

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

    Dijkstra();

    return 0;
}