Cod sursa(job #1473944)

Utilizator akaprosAna Kapros akapros Data 20 august 2015 15:49:08
Problema Ubuntzei Scor 65
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.48 kb
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
#define maxN 2002
#define maxK 17
#define maxP 32770
#define inf 2000000000
using namespace std;
int n, N[maxP], m, p, i, j, k, c, f[maxN], d[maxN], dist[maxK][maxP];
vector < pair <int, int> > V[maxN];
bool inq[maxN], inQ[maxK][maxP];
queue < int > q[maxP];
void read()
{
    int x, y, z;
    freopen("ubuntzei.in", "r", stdin);
    scanf("%d %d", &n, &m);
    scanf("%d", &k);
    for (i = 1; i <= k; ++ i)
    {
        scanf("%d", &c);
        f[c] = i;
    }

    p = 1 << k;
    for (i = 1; i <= m; ++ i)
    {
        scanf("%d %d %d", &x, &y, &z);
        V[x].push_back(make_pair(y, z));
        V[y].push_back(make_pair(x, z));
    }
}
void solve()
{
    int x, node, Pow;
    for (i = 1; i <= k; ++ i)
        for (j = 0; j < p; ++ j)
            dist[i][j] = inf;

    q[0].push(1);
    for (j = 0; j < p; ++ j)
    {
        for (i = 1; i <= n; ++ i)
        {
            d[i] = inf;
            if (f[i] && dist[f[i]][j] != inf)
                d[i] = dist[f[i]][j];
        }
        if (j == 0)
            d[1] = 0;

        while (!q[j].empty())
    {
        x = q[j].front();
        q[j].pop();
        inq[x] = 0;
        for (i = 0; i < V[x].size(); ++ i)
            {
                node = V[x][i].first;
                if (!f[node] || j & (1 << (f[node] - 1)))
                {
                    if (d[node] > d[x] + V[x][i].second)
                    {
                        d[node] = d[x] + V[x][i].second;
                        if (!inq[node])
                        {
                            q[j].push(node);
                            inq[node] = 1;
                        }
                    }
                }
                else
                {
                    Pow = 1 << (f[node] - 1);
                    if (dist[f[node]][j + Pow] > d[x] + V[x][i].second)
                    {
                        dist[f[node]][j + Pow] = d[x] + V[x][i].second;
                        if (!inQ[f[node]][j + Pow])
                        {
                            q[j + Pow].push(node);
                            inQ[f[node]][j + Pow] = 1;
                        }
                    }
                }

            }
    }
    }
}
void write()
{
    freopen("ubuntzei.out", "w", stdout);
    printf("%d", d[n]);
}
int main()
{
    read();
    solve();
    write();
    return 0;
}