Cod sursa(job #2674436)

Utilizator raducostacheRadu Costache raducostache Data 19 noiembrie 2020 10:42:14
Problema Ubuntzei Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.02 kb
//
//  main.cpp
//  ubunt
//
//  Created by Radu Costache on 18/11/2020.
//  Copyright © 2020 Radu Costache. All rights reserved.
//

#include <fstream>
#include <vector>
#include <queue>
#include <climits>
#include <algorithm>

#define INF INT_MAX
#define NMAX 2005
#define KMAX 17

using namespace std;

class Road {
public:
    int y, len;
    Road(int b, int c) {
        this->y = b;
        this->len = c;
    }
    Road() {
        this->y = 0;
        this->len = 0;
    }
};


int n, m, numberOfFriends;
int ans = INF;
int dp[(1 << KMAX)][KMAX];
int origin[NMAX];
int Friend[KMAX];
int cost[KMAX][NMAX];
vector <Road> v[NMAX];

int isSet(int, int);
inline void dijkstra(int, int*);

inline void read();
inline void solve();
inline void print();


int main(int argc, const char * argv[]) {
    // insert code here...
    read();
    solve();
    print();
    return 0;
}

inline void read() {
    ifstream f("ubuntzei.in");
    f >> n >> m;
    f >> numberOfFriends;
    for (int i = 0; i < numberOfFriends; ++i) {
        f >> Friend[i];
    }
    while (m--) {
        int x, y, c;
        f >> x >> y >> c;
        
        v[x].push_back(Road(y, c));
        v[y].push_back(Road(x, c));
    }
    
}

inline void solve() {
    dijkstra(1, origin);
    for (int i = 0; i < numberOfFriends ; ++i)
        dijkstra(Friend[i], cost[i]);
    for (int i = 1; i < (1 << numberOfFriends); ++i) {
        bool firstTime = 0;
        for (int j = 0; j < numberOfFriends; ++j) {
            if (i == (1 << j)) {
                dp[i][j] = origin[Friend[j]];
                firstTime = 1;
                break;
            }
        }
        if (!firstTime) {
            for (int j = 0; j < numberOfFriends; ++j) {
                dp[i][j] = INF;
                if (isSet(i, j)) {
                    for (int k = 0; k < numberOfFriends; ++k) {
                        if (k != j && isSet(i, k)) {
                            dp[i][j] = min(dp[i - (1 << j)][k] + cost[k][Friend[j]], dp[i][j]);
                        }
                    }
                }
            }
        }
    }
    for (int i = 0; i < numberOfFriends; ++i) {
        ans = min(ans, dp[(1 << numberOfFriends) - 1][i] + cost[i][n]);
    }
}

inline void print() {
    ofstream g("ubuntzei.out");
    g << ans << '\n';
}

int isSet(int x, int b) {
    return ((x & (1 << b)) != 0);
}

inline void dijkstra(int src, int* dist) {
    priority_queue<pair <int, int>, vector <pair<int, int>>, greater <pair<int, int>>> q;
    for (int i = 1; i <= n; ++i)
        dist[i] = INF;
    dist[src] = 0;
    for (int i = 1; i <= n; ++i)
        q.emplace(dist[i], i);
    while(!q.empty()) {
        pair <int, int> curr = q.top();
        q.pop();
        int node = curr.second;
        int distance = curr.first;
        
        if (dist[node] >= distance) {
            for (auto nxt:v[node]) {
                if (dist[nxt.y] > dist[node] + nxt.len) {
                    dist[nxt.y] = dist[node] + nxt.len;
                    q.emplace(dist[nxt.y], nxt.y);
                }
            }
        }
    }
    
}