Cod sursa(job #1460280)

Utilizator andreiiiiPopa Andrei andreiiii Data 12 iulie 2015 11:22:17
Problema Team Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.88 kb
#include <algorithm>
#include <fstream>
#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;

const int Pmax = 55, Nmax = 505, Inf = 0x3f3f3f3f;

int dp[Pmax][Pmax][Pmax];
int dest[Pmax];
int dist[Pmax][Pmax];

int nodeDist[Nmax];

vector<pair<int, int>> G[Nmax];

void dijkstra(int start) {
    priority_queue<pair<int, int>> Q;
    Q.push({0, start});
    memset(nodeDist, Inf, sizeof nodeDist);
    nodeDist[start] = 0;

    while (!Q.empty()) {
        int node = Q.top().second, cost = -Q.top().first;
        Q.pop();

        if (nodeDist[node] != cost) continue;

        for (const auto& p: G[node]) {
            if (nodeDist[p.first] > cost + p.second) {
                nodeDist[p.first] = cost + p.second;
                Q.push({-nodeDist[p.first], p.first});
            }
        }
    }
}

int main() {
    ifstream fin("team.in");
    ofstream fout("team.out");

    int P, N, M;
    fin >> P >> N >> M;

    while (M-- > 0) {
        int x, y, cost;
        fin >> x >> y >> cost;

        G[x].push_back({y, cost});
        G[y].push_back({x, cost});
    }

    for (int i = 1; i <= P; ++i)
        fin >> dest[i];

    dest[P + 1] = 1;
    for (int i = 1; i <= P + 1; ++i) {
        dijkstra(dest[i]);
        for (int j = 1; j <= P + 1; ++j)
            dist[i][j] = nodeDist[dest[j]];
    }

    for (int len = 1; len <= P; ++len) {
        for (int left = 1; left + len - 1 <= P; ++left) {
            int right = left + len - 1;

            for (int place = 1; place <= P + 1; ++place) {
                dp[left][right][place] = Inf;
                for (int i = left; i <= right; ++i)
                    dp[left][right][place] = min(dp[left][right][place],
                            dist[place][i] + dp[left][i - 1][i] + dp[i + 1][right][i]);
            }
        }
    }

    fout << dp[1][P][P + 1] << '\n';

    fin.close();
    fout.close();
}