Cod sursa(job #1012295)

Utilizator CosminRusuCosmin Rusu CosminRusu Data 18 octombrie 2013 17:31:43
Problema Team Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.89 kb
#include <fstream>
#include <vector>
#include <bitset>
#include <queue>

using namespace std;

string file = "team";

ifstream cin( (file + ".in").c_str() );
ofstream cout( (file + ".out").c_str() );

const int MAXN = 502;
const int MAXP = 52;
const int oo = 0x3f3f3f3f;

typedef pair<int, int> pii;
typedef vector<pii> Graph[MAXN];
typedef vector<pii> :: iterator It;

int N, M, P, X[MAXP][MAXN], dp[MAXP][MAXP][MAXP];
vector<int> dest(MAXP);
vector <int> d(MAXN, oo);
priority_queue < pii, vector<pii> , greater<pii> > Q;
Graph G;

inline void Dijkstra(int S) {
    fill(d.begin(), d.end(), oo);

    Q.push(make_pair(0, dest[S]));
    d[dest[S]] = 0;

    while(!Q.empty()) {
        int Node = Q.top().second;
        Q.pop();
        for(It it = G[Node].begin(), fin = G[Node].end(); it != fin ; ++ it)
            if(d[it->first] > d[Node] + it->second) {
                d[it->first] = d[Node] + it->second;
                Q.push(make_pair(d[it->first], it->first));
            }
    }
    for(int i = 1 ; i <= N ; ++ i)
        X[S][i] = d[i];
}

inline int DP(int i, int j, int k) {
    if( i>j || dp[i][j][k])
        return dp[i][j][k];
    dp[i][j][k] = oo;
    for(int l = i ; l <= j ; ++ l) {
        dp[i][j][k] = min(dp[i][j][k], DP(i, l-1, l) + DP(l + 1, j, l) + X[l][dest[k]]);
        if(!dp[i][j][k])
            break;
    }
    return dp[i][j][k];
}

int main() {
    cin >> P >> N >> M;
    for(int i = 1 ; i <= M ; ++ i) {
        int x, y, z;
        cin >> x >> y >> z;
        G[x].push_back(make_pair(y, z));
        G[y].push_back(make_pair(x, z));
    }
    for(int i = 1 ; i <= P ; ++ i) {
        cin >> dest[i];
        Dijkstra(i);
    }
    dest[0] = 1;
    /// DP[i][j][k] = costul minim pentru a ajunge cu oamenii i...j pornind din casa lui k;
    cout << DP(1, P, 0);
    cin.close();
    cout.close();
    return 0;
}