Cod sursa(job #2935389)

Utilizator LuciBBadea Lucian LuciB Data 6 noiembrie 2022 17:22:57
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.29 kb
#include <bits/stdc++.h>
using namespace std;

const int NMAX = 2000;
const int KMAX = 15;
const int INF = 1e9;

struct Edge {
	int neighbour, cost;
};

vector<Edge> graph[NMAX + 1];

int ubuntzei[KMAX + 2];
int dist[NMAX + 1];
int cost[KMAX + 2][KMAX + 2];

int dp[(1 << (KMAX + 2))][KMAX + 2];

void dijkstra(int node) {
    queue<pair<int, int>> q;
    dist[node] = 0;
    q.push({0, node});
    while(!q.empty()) {
        auto qFront = q.front();
        q.pop();
        if(qFront.first <= dist[qFront.second]) {
            for(auto x : graph[qFront.second]) {
                if(x.cost + dist[qFront.first] < dist[x.neighbour]) {
                    dist[x.neighbour] = x.cost + dist[qFront.first];
                    q.push({dist[x.neighbour], x.neighbour});
                }
            }
        }
    }
}

int main() {
	FILE *fin, *fout;
	fin = fopen("ubuntzei.in", "r");
	fout = fopen("ubuntzei.out", "w");
	int n, m, k;
    fscanf(fin, "%d%d%d", &n, &m, &k);
    ubuntzei[0] = 1;
    ubuntzei[k + 1] = n;
    for(int i = 1; i <= k; i++) {
        fscanf(fin, "%d", &ubuntzei[i]);
    }
    for(int i = 0; i < m; i++) {
        int a, b, c;
        fscanf(fin, "%d%d%d", &a, &b, &c);
        graph[a].push_back({b, c});
        graph[b].push_back({a, c});
    }
    for(int i = 0; i < k + 2; i++) {
        for(int j = 0; j < k + 2; j++) {
            cost[i][j] = INF;
        }
    }
    for(int i = 0; i < k + 2; i++) {
        for(int j = 1; j <= n; j++)
            dist[j] = INF;
        dijkstra(ubuntzei[i]);
        for(int j = 0; j < k + 2; j++) {
            cost[i][j] = cost[j][i] = dist[ubuntzei[j]];
        }
    }
    for(int mask = 0; mask < (1 << (k + 2)); mask++)
        for(int i = 0; i < k + 2; i++)
            dp[mask][i] = INF;
    dp[1][0] = 0;
    for(int mask = 3; mask < (1 << (k + 2)); mask += 2) {
        for(int i = 1; i < k + 2; i++) {
            if(mask & (1 << i)) {
                for(int j = 0; j < k + 2; j++) {
                    if(cost[j][i])
                        dp[mask][i] = min(dp[mask][i], dp[mask ^ (1 << i)][j] + cost[j][i]);
                }
            }
        }
    }
    fprintf(fout, "%d", dp[(1 << (k + 2)) - 1][k + 1] + 1);

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