Cod sursa(job #2036713)

Utilizator anisca22Ana Baltaretu anisca22 Data 10 octombrie 2017 23:40:40
Problema Ubuntzei Scor 75
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.24 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#define NMAX 2005
#define UMAX 65536
#define pii pair <int, int>
#define INF 0x3f3f3f3f
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");

struct str{
    int nod, cost;

    bool operator < (const str &other) const{
        return cost > other.cost;
    }
};

int n, m, k, rsp;
int c[NMAX];
int dist[NMAX][NMAX], dp[UMAX][20];
vector <pii> v[NMAX];
priority_queue <str> pq;

void dijkstra(int start)
{
    pq.push({start, 0});
    while (!pq.empty())
    {
        vector <pii> :: iterator it;
        int nod = pq.top().nod;
        int cost = pq.top().cost;
        pq.pop();
        if (dist[start][nod] != cost) continue;

        for (it = v[nod].begin(); it != v[nod].end(); it++)
        {
            pii nr = *it;
            int nxt = nr.first;
            int cst = nr.second;
            if (dist[start][nod] + cst < dist[start][nxt])
            {
                dist[start][nxt] = dist[start][nod] + cst;
                pq.push({nxt,dist[start][nxt]});
            }
        }
    }
}

int main()
{
    fin >> n >> m >> k;
    for (int i = 1; i <= k; i++)
        fin >> c[i];
    c[++k] = n;
    for (int i = 1; i <= m; i++)
    {
        int x, y, c;
        fin >> x >> y >> c;
        v[x].push_back({y, c});
        v[y].push_back({x, c});
    }
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (i != j)
                dist[i][j] = INF;
    dijkstra(1);
    for (int i = 1; i <= k; i++)
        dijkstra(c[i]);

    for (int i = 0; i < (1 << (k + 1)); i++)
        for (int j = 0; j <= k; j++)
            dp[i][j] = INF;

    for (int i = 0; i < k; i++)
        dp[(1 << i)][i] = dist[1][c[i + 1]];

    for (int i = 1; i < (1 << k); i++)
        for (int j = 0; j <= k; j++)
        {
            int ii = i & ~(1 << j);
            if (i != ii)
                for (int jj = 0; jj <= k; jj++)
                    dp[i][j] = min(dp[ii][jj] + dist[c[jj + 1]][c[j + 1]],dp[i][j]);
        }

    rsp = INF;
    for (int i = 0; i <= k; i++)
        rsp = min(rsp, dp[(1 << k) - 1][i] + dist[c[i + 1]][n]);
    fout << rsp;
    return 0;
}