Cod sursa(job #2327168)

Utilizator FrequeAlex Iordachescu Freque Data 24 ianuarie 2019 14:32:28
Problema Ubuntzei Scor 75
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.09 kb
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define enter cout << '\n'

using namespace std;

typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef vector <int> vi;
typedef vector <pii> vii;
typedef vector <ll> vl;
typedef vector <pll> vll;
typedef queue <int> qi;
typedef queue <pii> qii;
typedef queue <ll> ql;
typedef queue <pll> qll;

const int INF = 0x3f3f3f3f;
const int MOD = 998244353;
const int EPSILON = 0.0000000001;
//const int NMAX = 2000 + 5;
const int NMAX = 50000 + 5;
const int MMAX = 1e4 + 5;
const int KMAX = 15 + 5;
const int EMAX = (1 << 16);

ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");

struct edge
{
    int node, cost;

    edge()
    {
        node = cost = 0;
    }

    edge(int _n, int _c)
    {
        node = _n;
        cost = _c;
    }

    bool operator <(const edge &arg) const
    {
        return cost > arg.cost;
    }
};

priority_queue <edge> pq;
vector <edge> graph[NMAX], comp[KMAX];
int n, m, k;
int prieten[KMAX], dist[NMAX];
int dp[EMAX][KMAX];
bool vis[NMAX];

void dijkstra(int start)
{
    memset(dist, INF, sizeof(dist));
    dist[start] = 0;
    pq.push(edge(start, 0));
    while (!pq.empty())
    {
        edge nod = pq.top();
        pq.pop();
        if (nod.cost > dist[nod.node]) continue;
        for (edge next: graph[nod.node])
            if (dist[next.node] > dist[nod.node] + next.cost)
            {
                dist[next.node] = dist[nod.node] + next.cost;
                if (!vis[next.node]) pq.push(edge(next.node, dist[next.node]));
            }
    }
}

void read()
{
    int x, y, c;

    fin >> n >> m >> k;
    for (int i = 1; i <= k; ++i)
    {
        fin >> prieten[i];
        --prieten[i];
    }
    for (int i = 1; i <= m; ++i)
    {
        fin >> x >> y >> c;
        graph[x - 1].pb(edge(y - 1, c));
        graph[y - 1].pb(edge(x - 1, c));
    }
}

int main()
{
    read();

    dijkstra(0);
    for (int i = 1; i <= k; ++i)
    {
        comp[0].pb(edge(i, dist[prieten[i]]));
        comp[i].pb(edge(0, dist[prieten[i]]));
    }
    comp[0].pb(edge(k + 1, dist[n - 1]));
    comp[k + 1].pb(edge(0, dist[n - 1]));

    for (int i = 1; i <= k; ++i)
    {
        dijkstra(prieten[i]);
        for (int j = i + 1; j <= k; ++j)
        {
            comp[i].pb(edge(j, dist[prieten[j]]));
            comp[j].pb(edge(i, dist[prieten[j]]));
        }
        comp[i].pb(edge(k + 1, dist[n - 1]));
        comp[k + 1].pb(edge(i, dist[n - 1]));
    }

    memset(dp, INF, sizeof(dp));
    dp[1][0] = 0;
    for (int mask = 1; mask < (1 << (k + 2)); ++mask)
        for (int i = 0; i < k + 2; ++i)
            if (mask & (1 << i))
                for (edge j: comp[i])
                    if (mask & (1 << j.node))
                        dp[mask][i] = min(dp[mask][i], dp[mask ^ (1 << i)][j.node] + j.cost);

    fout << dp[(1 << (k + 2)) - 1][k + 1];

    return 0;
}