Cod sursa(job #2054334)

Utilizator Alex18maiAlex Enache Alex18mai Data 1 noiembrie 2017 21:32:57
Problema Team Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.82 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];

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;
    }

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

    int ans = inf;

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

    cout << ans;

    return 0;
}