Cod sursa(job #2054284)

Utilizator Alex18maiAlex Enache Alex18mai Data 1 noiembrie 2017 20:49:56
Problema Team Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.36 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 k = 1; k <= p; k++) {
        for (int i = 1; i <= k; i++) {
            for (int j = k; j <= p; j++) {
                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;
                    //cout<<"st "<<DP[i][k-1][s]<<" "<<mat[k][s]<<'\n';
                    st = min(st, DP[i][k - 1][s] + mat[k][s]);
                }
                for (int d = k + 1; d <= j; d++) {
                    intrat_dr = true;
                    //cout<<"dr "<<DP[k+1][j][d]<<" "<<mat[d][k]<<'\n';
                    dr = min(dr, DP[k + 1][j][d] + mat[d][k]);
                }
                if (!intrat_st) {
                    st = 0;
                }
                if (!intrat_dr) {
                    dr = 0;
                }
                DP[i][j][k] = min(DP[i][j][k], st + dr);
               /* if (DP[i][j][k] < inf) {
                    cout << i << " " << j << " " << k << " " << DP[i][j][k] << '\n';
                }*/
                //cout<<DP[i][j][k]<<" "<<st + dr<<'\n';
            }
        }
    }

    for (int k = 1; k <= p; k++) {
        for (int i = 1; i <= k; i++) {
            for (int j = k; j <= p; j++) {
                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;
                    //cout<<"st "<<DP[i][k-1][s]<<" "<<mat[k][s]<<'\n';
                    st = min(st, DP[i][k - 1][s] + mat[k][s]);
                }
                for (int d = k + 1; d <= j; d++) {
                    intrat_dr = true;
                    //cout<<"dr "<<DP[k+1][j][d]<<" "<<mat[d][k]<<'\n';
                    dr = min(dr, DP[k + 1][j][d] + mat[d][k]);
                }
                if (!intrat_st) {
                    st = 0;
                }
                if (!intrat_dr) {
                    dr = 0;
                }
                DP[i][j][k] = min(DP[i][j][k], st + dr);
                /*if (DP[i][j][k] < inf) {
                    cout << i << " " << j << " " << k << " " << DP[i][j][k] << '\n';
                }*/
                //cout<<DP[i][j][k]<<" "<<st + dr<<'\n';
            }
        }
    }



    int ans = inf;

    for (int i = 1; i <= p; i++) {
        //cout << "DP " << 1 << " " << p << " " << i << " " << DP[1][p][i] << '\n';
        ans = min(ans, DP[1][p][i] + mat[0][i]);
    }

    cout << ans;

    return 0;
}