Cod sursa(job #1729650)

Utilizator mariakKapros Maria mariak Data 15 iulie 2016 13:21:36
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.92 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;

//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.s > b.s;
    }
};
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 lg[(1 << Kmax) + 2];
int d[Kmax][(1 << Kmax) + 2];
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)
{
    u = heap.top().f;
    cost = heap.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) == 1)
            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]]]);

            }
        }
    }
}
class InputReader
{
public:
    InputReader() {}
    InputReader(const char *file_name)
    {
        input_file = fopen(file_name, "r");
        cursor = 0;
        fread(buffer, SIZE, 1, input_file);
    }
    inline InputReader &operator >>(int &n)
    {
        while(buffer[cursor] < '0' || buffer[cursor] > '9')
        {
            advance();
        }
        n = 0;
        while('0' <= buffer[cursor] && buffer[cursor] <= '9')
        {
            n = n * 10 + buffer[cursor] - '0';
            advance();
        }
        return *this;
    }
private:
    FILE *input_file;
    static const int SIZE = 1 << 17;
    int cursor;
    char buffer[SIZE];
    inline void advance()
    {
        ++ cursor;
        if(cursor == SIZE)
        {
            cursor = 0;
            fread(buffer, SIZE, 1, input_file);
        }
    }
};

void read()
{
    int i, u, v, cost;
    InputReader cin("ubuntzei.in");
    cin >> N >> M >> K;
    for (i = 0; i < K; ++ i)
        cin >> take[i];

    for (i = 1; i <= M; ++ i)
    {
        cin >> u >> v >> cost;
        G[u].pb(pii(v, cost));
        G[v].pb(pii(u, cost));
    }
}
void solve()
{
    int i;
    dijkstra(1);
    for (i = 0; i < K; ++ i)
    {
        F.reset();
        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;
}