Cod sursa(job #1734768)

Utilizator akaprosAna Kapros akapros Data 28 iulie 2016 10:43:29
Problema Team Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.68 kb
#include <bits/stdc++.h>
#define maxN 502
#define maxP 52
#define pb push_back
#define mp make_pair
#define f first
#define s second
#define pii pair < short int, int >
#define inf 1000000000
using namespace std;
int n, m, p, c[maxP][maxN], home[maxP], dp[maxP][maxP][maxP], ans;
int ish[maxN];
vector < pii > V[maxN];
struct pq
{
    int x, c;
    bool operator < (const pq & e) const
    {
        return c > e.c;
    }
};
priority_queue < pq > H;
void read()
{
    freopen("team.in", "r", stdin);
    scanf("%d %d %d", &p, &n, &m);
    while (m --)
    {
        int x, y, c;
        scanf("%d %d %d", &x, &y, &c);
        V[x].pb(mp(y, c));
        V[y].pb(mp(x, c));
    }
}
void Dijkstra(int x)
{
    int i, j;
    pq a;
    for (i = 1; i <= n; ++ i)
    {
        if (ish[i])
        {
            c[x][i] = c[ish[i]][home[x]];
            a.x = i;
            a.c = c[x][i];
            H.push(a);
        }
        else
            c[x][i] = inf;
    }
    c[x][home[x]] = 0;
    a.x = home[x];
    a.c = 0;
    H.push(a);
    while (!H.empty())
    {
        pq el = H.top();
        H.pop();
        int y, nod = el.x;
        if (c[x][nod] != el.c)
            continue;
        for (j = 0; j < V[nod].size(); ++ j)
            if (c[x][y = V[nod][j].f] > c[x][nod] + V[nod][j].s)
            {
                int cost = c[x][nod] + V[nod][j].s;
                c[x][y = V[nod][j].f] = cost;
                a.x = y;
                a.c = cost;
                H.push(a);
            }
    }
}
void Dp()
{
    int i, j, k, x;
    for (i = p; i >= 1; -- i)
        for (j = i + 1; j <= p; ++ j)
            for (k = i; k <= j; ++ k)
            {
                int a = inf, b = inf;
                for (x = i; x < k; ++ x)
                    if (a > dp[i][k - 1][x] + c[x][home[k]])
                        a = dp[i][k - 1][x] + c[x][home[k]];
                if (k == i)
                    a = 0;
                for (x = k + 1; x <= j; ++ x)
                    if (b > dp[k + 1][j][x] + c[x][home[k]])
                        b = dp[k + 1][j][x] + c[x][home[k]];
                if (k == j)
                    b = 0;
                dp[i][j][k] = a + b;
                if (i == 1 && j == p && ans > dp[i][j][k] + c[k][1])
                    ans = dp[i][j][k] + c[k][1];
            }
}
void solve()
{
    int i;
    ans = inf;
    for (i = 1; i <= p; ++ i)
    {
        scanf("%d", &home[i]);
        Dijkstra(i);
        ish[home[i]] = i;
    }
    Dp();
}
void write()
{
    freopen("team.out", "w", stdout);
    printf("%d\n", ans);
}
int main()
{
    read();
    solve();
    write();
    return 0;
}