Cod sursa(job #2054348)

Utilizator Alex18maiAlex Enache Alex18mai Data 1 noiembrie 2017 21:42:27
Problema Team Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.59 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

ifstream cin("team.in");
ofstream cout("team.out");

int p, n, m;

class cmp {
public:
    bool operator()(pair<int, int> a, pair<int, int> b) {
        return a.second > b.second;
    }
};

vector<vector<pair<int, int> > > gr(505);

int loc[55];

int dp[505];
int mat[55][55];
priority_queue<pair<int, int>, vector<pair<int, int> >, cmp> Q;

const int inf = 1e9;

void put_inf() {
    for (int i = 1; i <= n; i++) {
        dp[i] = inf;
    }
}

void dijkstra(int root) {

    put_inf();

    dp[loc[root]] = 0;
    Q.push({loc[root], 0});

    while (!Q.empty()) {
        pair<int, int> now = Q.top();
        Q.pop();
        if (dp[now.first] != now.second) {
            continue;
        }
        for (auto &x : gr[now.first]) {
            if (dp[x.first] > now.second + x.second) {
                dp[x.first] = now.second + x.second;
                Q.push({x.first, dp[x.first]});
            }
        }
    }

    for (int i = 0; i <= p; i++) {
        mat[root][i] = dp[loc[i]];
        //cout<<mat[root][i]<<" ";
    }
    //cout<<'\n';

}

int DP[55][55][55];

int memo(int i , int j , int k){
    if (DP[i][j][k] != inf){
        return DP[i][j][k];
    }
        int ST = inf;
        bool intrat_st = false;
        int DR = inf;
        bool intrat_dr = false;
        for (int s = i; s <= k - 1; s++) {
            intrat_st = true;
            ST = min(ST, memo(i , k-1, s) + mat[k][s]);
        }
        for (int d = k + 1; d <= j; d++) {
            intrat_dr = true;
            DR = min(DR, memo(k+1 , j , d)+ mat[d][k]);
        }
        if (!intrat_st) {
            ST = 0;
        }
        if (!intrat_dr) {
            DR = 0;
        }
        DP[i][j][k] = ST + DR;
        return DP[i][j][k];

}

void put_inf_DP() {
    for (int i = 0; i <= p; i++) {
        for (int j = 0; j <= p; j++) {
            for (int k = 0; k <= p; k++) {
                DP[i][j][k] = inf;
            }
        }
    }
}

int main() {

    ios::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> p >> n >> m;

    for (int i = 1; i <= m; i++) {
        int a, b, val;
        cin >> a >> b >> val;

        gr[a].push_back({b, val});
        gr[b].push_back({a, val});
    }

    for (int i = 1; i <= p; i++) {
        cin >> loc[i];
    }

    loc[0] = 1;

    for (int i = 0; i <= p; i++) {
        dijkstra(i);
    }

    put_inf_DP();

    for (int i = 0; i <= p; i++) {
        DP[i][i][i] = 0;
    }

    int ans = inf;

    for (int i = 1; i <= p; i++) {
        ans = min(ans, memo(1 , p , i) + mat[0][i]);
    }

    cout << ans;

    return 0;
}