Cod sursa(job #1725606)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 6 iulie 2016 00:08:05
Problema Team Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.76 kb
#include <fstream>
#include <cstring>
#include <cassert>

using namespace std;

constexpr int MAX_N = 500;
constexpr int MAX_P = 50;
constexpr int INF = 0x3f3f3f3f;
constexpr int NIL = -1;

int edgeCost[MAX_N][MAX_N];

int residence[MAX_P + 1];
int dp[MAX_P][MAX_P][MAX_P + 1];

int pathWeight[MAX_P + 1][MAX_N];
bool color[MAX_N];

void Dijkstra(const int node,
              const int n,
              int weight[]) {
    memset(weight, 0x3f, 4 * n);
    memset(color, 0, n);
    weight[node] = 0;
    int best = node;
    for (int i = n - 1; i >= 0; i -= 1) {
        const int u = best;
        color[u] = true;
        int bestCost = INF;
        for (int son = 0; son < n; son += 1) {
            if (not(color[son])) {
                if (weight[son] > weight[u] + edgeCost[u][son]) {
                    weight[son] = weight[u] + edgeCost[u][son];
                }
                if (weight[son] < bestCost) {
                    bestCost = weight[son];
                    best = son;
                }
            }
        }
    }
}

int memo(const int b, const int e, const int node) {
    if (dp[b][e][node] != NIL) {
        return dp[b][e][node];
    }
    if (b > e) {
        return 0;
    } else if (b == e) {
        return dp[b][e][node] = pathWeight[b + 1][residence[node]];
    } else {
        int x = INF;
        for (int opt = b; opt <= e; opt += 1) {
            const int option = memo(b, opt - 1, opt + 1)
                             + pathWeight[node][residence[opt + 1]]
                             + memo(opt + 1, e, opt + 1);
            if (x > option) {
                x = option;
            }
        }
        return dp[b][e][node] = x;
    }
}

int main() {
    ifstream fin("team.in");
    ofstream fout("team.out");
    fin.tie(0);
    ios_base::sync_with_stdio(false);
    int p, n, e; fin >> p >> n >> e;
    for (int i = 0; i < n; i += 1) {
        for (int j = 0; j < n; j += 1) {
            edgeCost[i][j] = INF;
        }
    }
    for (int i = 0; i < e; i += 1) {
        int node_1, node_2, weight; fin >> node_1 >> node_2 >> weight;
        if (weight < edgeCost[node_1 - 1][node_2 - 1]) {
            edgeCost[node_1 - 1][node_2 - 1] = edgeCost[node_2 - 1][node_1 - 1] = weight;
        }
    }
    for (int i = 0; i <= p; i += 1) {
        if (i) {
            fin >> residence[i]; residence[i] -= 1;
        }
        Dijkstra(residence[i],
                 n,
                 pathWeight[i]);
    }
    for (int i = 0; i < p; i += 1) {
        for (int j = 0; j < p; j += 1) {
            for (int k = 0; k <= p; k += 1) {
                dp[i][j][k] = NIL;
            }
        }
    }
    fout << memo(0, p - 1, 0) << '\n';
    fout.close();
    return 0;
}