Cod sursa(job #2982805)

Utilizator cberindeCodrin Berinde cberinde Data 20 februarie 2023 21:37:14
Problema Ubuntzei Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.43 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");

struct muchie {
    long long nod, cost;
    bool operator < (const muchie &a) const {
        return a.cost < cost;
    }
};

long long n, m, k;
long long pitici[16];
long long distante[18][18];
vector<pair<long long, long long>> adi[2001];
long long dist[2001];
bool vizi[2001];
priority_queue<muchie> q;
long long dp[16][(1 << 15)];

void dijkstra(long long start, long long pitic) {
    muchie y;
    for(long long i = 1; i <= n; i++) {
        dist[i] = __LONG_LONG_MAX__;
        vizi[i] = false;
    }
    while(!q.empty()) {
        q.pop();
    }
    dist[start] = 0;
    vizi[start] = true;
    y.nod = start;
    y.cost = 0;
    q.push(y);
    while(!q.empty()) {
        long long ncrt = q.top().nod;
        vizi[ncrt] = true;
        q.pop();
        for(auto nou : adi[ncrt]) {
            if(!vizi[nou.first] && dist[ncrt] + nou.second < dist[nou.first]) {
                dist[nou.first] = dist[ncrt] + nou.second;
                y.nod = nou.first;
                y.cost = dist[nou.first];
                q.push(y);
            }
        }
    }

    // cout << "Dupa dijkstra din " << start << " avem distantele: ";
    // for(long long i = 1; i <= n; i++) {
    //     cout << dist[i] << " ";
    // }
    // cout << "\n";

    distante[pitic][k + 1] = dist[1]; //distanta pana la nodul 1
    distante[pitic][k + 2] = dist[n]; // distanta pana la nodul n
    for(long long i = 1; i <= k; i++) {
        distante[pitic][i] = dist[pitici[i]];
    }
}

int main() {
    fin >> n >> m >> k;
    for(long long i = 1; i <= k; i++) {
        fin >> pitici[i];
    }
    long long a, b, c;
    for(long long i = 1; i <= m; i++) {
        fin >> a >> b >> c;
        adi[a].push_back(make_pair(b, c));
        adi[b].push_back(make_pair(a, c));
    }
    for(long long i = 1; i <= k; i++) {
        dijkstra(pitici[i], i);
    }
    dijkstra(1, k + 1);
    dijkstra(n, k + 2);
    if(k == 0) {
        fout << distante[1][2];
        return 0;
    }
    // for(long long i = 1; i <= k + 2; i++) {
    //     for(long long j = 1; j <= k + 2; j++) {
    //         cout << distante[i][j] << " ";
    //     }
    //     cout << endl;
    // }

    for(long long i = 1; i <= k; i++) {
        for(long long conf = 0; conf < (1 << k); conf++) {
            dp[i][conf] = __LONG_LONG_MAX__;
        }
    }
    //incepem dp-ul
    for(long long i = 1; i <= k; i++) {
        dp[i][(1 << (i - 1))] = distante[k + 1][i];
    }
    for(long long conf = 1; conf < (1 << k); conf++) {
        for(long long sursa = 1; sursa <= k; sursa++) {
            if((conf & (1 << (sursa - 1))) != 0) {
                for(long long nod = 1; nod <= k; nod++) {
                    if((conf & (1 << (nod - 1))) != 0 && nod != sursa) {
                        if(dp[nod][conf] > dp[sursa][conf ^ (1 << (sursa - 1))] + distante[nod][sursa]) {
                            dp[nod][conf] = dp[sursa][conf ^ (1 << (sursa - 1))] + distante[nod][sursa];
                        }
                    }
                }
            }
        }
    }
    long long rez = __LONG_LONG_MAX__;
    for(long long i = 1; i <= k; i++) {
        if(rez > dp[i][(1 << k) - 1] + distante[i][k + 2]) {
            rez = dp[i][(1 << k) - 1] + distante[i][k + 2];
        }
    }
    fout << rez;
    return 0;
}