Cod sursa(job #1734533)

Utilizator akaprosAna Kapros akapros Data 27 iulie 2016 16:46:37
Problema Ubuntzei Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.49 kb
#include <bits/stdc++.h>
#define maxN 2002
#define maxM 10002
#define maxS (1 << 15) + 2
#define maxK 17
#define pb push_back
#define mp make_pair
#define f first
#define s second
#define pii pair < int, int >
#define inf 1000000000
using namespace std;
int n, m, k, c[maxK], dp[maxK][maxS], dist[maxN][maxN], ans;
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()
{
    int i;
    freopen("ubuntzei.in", "r", stdin);
    scanf("%d %d", &n, &m);
    scanf("%d", &k);
    for (i = 1; i <= k; ++ i)
        scanf("%d", &c[i]);
    while (m --)
    {
        int x, y, cost;
        scanf("%d %d %d", &x, &y, &cost);
        V[x].pb(mp(y, cost));
        V[y].pb(mp(x, cost));
    }
}
void Dijkstra()
{
    int i, j, x;
    pq a;
    for (x = 1; x <= k; ++ x)
    {
        for (i = 1; i <= n; ++ i)
            dist[x][i] = inf;
        dist[x][c[x]] = 0;
        a.x = c[x];
        a.c = 0;
        H.push(a);
        while (!H.empty())
        {
            pq el = H.top();
            H.pop();
            int y, nod = el.x;
            for (j = 0; j < V[nod].size(); ++ j)
                if (dist[x][y = V[nod][j].f] > dist[x][nod] + V[nod][j].s)
                {
                    int cost = dist[x][nod] + V[nod][j].s;
                    dist[x][y = V[nod][j].f] = cost;
                    a.x = y;
                    a.c = cost;
                    H.push(a);
                }
        }
    }
}
void Dp()
{
    int i, j, st;
    ans = inf;
    for (st = 1; st < (1 << k); ++ st)
        for (i = 0; i < k; ++ i)
            if (st & (1 << i))
            {
                dp[i][st] = inf;
                if (st == (1 << i))
                    dp[i][st] = dist[i + 1][1];
                else
                {
                    for (j = 0; j < k; ++ j)
                        if (i != j && st & (1 << j) && dp[i][st] > dp[j][st ^ (1 << i)] + dist[i + 1][c[j + 1]])
                            dp[i][st] = dp[j][st ^ (1 << i)] + dist[i + 1][c[j + 1]];
                }
                if (st == (1 << k) - 1 && ans > dp[i][st] + dist[i + 1][n])
                    ans = dp[i][st] + dist[i + 1][n];
            }
}
void solve()
{
    Dijkstra();
    Dp();
}
void write()
{
    freopen("ubuntzei.out", "w", stdout);
    printf("%d\n", ans);
}
int main()
{
    read();
    solve();
    write();
    return 0;
}