Cod sursa(job #1729629)

Utilizator mariakKapros Maria mariak Data 15 iulie 2016 12:56:52
Problema Ubuntzei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.1 kb
#include <bits/stdc++.h>
#define Nmax 2002
#define pii pair <int, int>
#define f first
#define s second
#define pb(x) push_back(x)
#define Kmax 15
#define INF 1 << 30
using namespace std;
using std::priority_queue;
using std::vector;

FILE *fin  = freopen("ubuntzei.in", "r", stdin);
FILE *fout = freopen("ubuntzei.out", "w", stdout);
struct comp
{
    bool operator() (const pii &a, const pii &b)
    {
        return a.second > b.second;
    }
};
priority_queue< pii, vector< pii >, comp > heap;
int N, M, K, sol;
bitset <Nmax> F;
vector <pii> G[Nmax];
int pow2[Kmax];
int take[Kmax];
int bits[Kmax];
int adj[Nmax];
int lg[(1 << Kmax) + 1];
int d[Kmax][(1 << Kmax) + 1];
int dist[Nmax][Nmax];

int Min(int x, int y)
{
    return x < y ? x : y;
}

void initial(int x)
{
    for (int i = 1; i <= N; i++)
        dist[x][i] = INF;
}
void add_heap(int u, int source, int cost)
{
    dist[source][u] = cost;
    heap.push(pii(u, cost));
}
void extract_heap(int &u, int &cost)
{
    pii top = heap.top();
    u = top.f;
    cost = top.s;
    heap.pop();
}
void dijkstra(int source)
{
    int u, v, pos, cost, w;

    initial(source);
    add_heap(source, source, 0);

    while (!heap.empty())
    {
        extract_heap(u, cost);
        if(F.test(u)) continue;
        int sz = G[u].size();
        for (int i = 0; i < sz; ++ i)
        {
            v = G[u][i].f;
            w = cost + G[u][i].s;
            if (F.test(v) == 0 && w < dist[source][v])
                add_heap(v, source, w);

        }
        F.set(u);
    }
}

void analyze(int s)
{
    int i, j, save, last, sz = 0;
    if (s & (s - 1))
    {
        for (save = s; save; save ^= last)
        {
            /// the last bit
            last = save & -save;
            bits[sz ++] = lg[last];
        }
        for (i = 0; i < sz; ++ i)
        {
            d[bits[i]][s] = INF;
            for (j = 0; j < sz; ++ j)
            {
                if (i != j)
                    d[bits[i]][s] = Min(d[bits[i]][s],
                        d[bits[j]][s ^ pow2[bits[i]]] + dist[take[bits[i]]][take[bits[j]]]);

            }
        }
    }
}

void read()
{
    int i, u, v, cost;

    scanf("%d %d %d", &N, &M, &K);
    for (i = 0; i < K; ++ i)
        scanf("%d", &take[i]);

    for (i = 1; i <= M; ++ i)
    {
        scanf("%d %d %d", &u, &v, &cost);
        G[u].pb(pii(v, cost));
        G[v].pb(pii(u, cost));
    }
}
void solve()
{
    int i;
    dijkstra(1);
    F.reset();
    for (i = 0; i < K; ++ i)
        dijkstra(take[i]);

    ///initial
    for (i = 0; i < K; ++ i)
    {
        pow2[i] = 1 << i;
        d[i][pow2[i]] = dist[1][take[i]];
        lg[pow2[i]] = i;
    }

    int total = (1 << K) - 1;
    for (i = 1; i <= total; ++ i)
        analyze(i);

    sol = INF;
    if (K == 0)
        sol = dist[1][N];

    else
        for (i = 0; i < K; ++ i)
            sol = Min(sol, d[i][total] + dist[take[i]][N]);
}
void write()
{
    printf("%d\n", sol);
}
int main()
{
    read();
    solve();
    write();
    return 0;
}