Cod sursa(job #1012289)

Utilizator CosminRusuCosmin Rusu CosminRusu Data 18 octombrie 2013 17:28:41
Problema Team Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.67 kb
#include <fstream>
#include <vector>
#include <bitset>
#include <queue>
#include <algorithm>
#include <utility>
#include <cstring>
#include <string>
#include <stack>
#include <deque>
#include <iomanip>
#include <set>
#include <map>
#include <cassert>
#include <ctime>
#include <list>
#include <iomanip>

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;

const inline int min(const int &a, const int &b) { if( a > b ) return b;   return a; }
const inline int max(const int &a, const int &b) { if( a < b ) return b;   return a; }
const inline void Get_min(int &a, const int b)    { if( a > b ) a = b; }
const inline void Get_max(int &a, const int b)    { if( a < b ) a = b; }

struct ClassComp {
    inline bool operator () (const int &a, const int &b) const {
        return a > b;
    }
};

int N, M, P, X[MAXP][MAXN], dp[MAXP][MAXP][MAXP];
vector<int> dest(MAXP);
vector <int> d(MAXN, oo);
queue <int> Q;
bitset <MAXN> inQ;
Graph G;

inline void BF(int S) {
    fill(d.begin(), d.end(), oo);
    //Bellman Ford
    Q.push(dest[S]);
    d[dest[S]] = 0;
    inQ[dest[S]] = true;

    while(!Q.empty()) {
        int Node = Q.front();
        Q.pop();
        inQ[Node] = false;
        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;
                if(!inQ[it->first]){
                    Q.push(it->first);
                    inQ[it->first] = true;
                }
            }
    }
    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];
        BF(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;
}