Cod sursa(job #1472586)

Utilizator TimitocArdelean Andrei Timotei Timitoc Data 17 august 2015 13:16:10
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.76 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>

#define MAXN 2011
#define MAXK 16
#define INF 0x3fffffff;

using namespace std;

int n, m, k;

struct vecin
{
    int y, cost;
    vecin(int y = 0, int cost = 0) : y(y), cost(cost) {}
    bool operator()(vecin a, vecin b)
    {
        return a.cost > b.cost;
    }
};

vector<vecin> graf[MAXN];
int necs[MAXK+1]; // necs 0 is for starting 1 dijkstra
int bests[MAXK+1][MAXN];

void citire()
{
    scanf("%d %d", &n, &m);
    scanf("%d", &k);
    necs[0] = 1;
    for (int i = 1; i <= k; i++)
    {
        scanf("%d", &necs[i]);
    }
    int x, y, z;
    for (int i = 1; i <= m; i++)
    {
        scanf("%d %d %d", &x, &y, &z);
        graf[x].push_back(vecin(y, z));
        graf[y].push_back(vecin(x, z));
    }
}
priority_queue<vecin, vector<vecin>, vecin> q;
void dijkstra(int start, int best[MAXN])
{
    while (!q.empty()) q.pop();
    q.push(vecin(start, 0));
    for (int i = 0; i <= n; i++)
        best[i] = INF;
    best[start] = 0;
    while (!q.empty())
    {
        vecin top = q.top();
        q.pop();
        for (unsigned i = 0; i < graf[top.y].size(); i++)
        {
            vecin next = graf[top.y][i];
            if (best[next.y] > top.cost + next.cost)
            {
                best[next.y] = top.cost + next.cost;
                q.push(vecin(next.y, best[next.y]));
            }
        }
    }
}
int sol[MAXK+1][1<<15];
struct cmp
{
    bool operator()(pair<int, int> a, pair<int, int> b)
    {
        return sol[a.first][a.second] > sol[b.first][b.second];
    }
};
priority_queue<pair<int, int>, vector<pair<int, int> >, cmp> q2;
int solve()
{
    for (int i = 0; i <= k; i++)
        for (int j = 0; j < (1<<k); j++)
            sol[i][j] = INF;
    sol[0][0] = 0;
    q2.push(make_pair(0, 0));
    while (!q2.empty())
    {
        pair<int, int> top = q2.top();
        q2.pop();
        for (int i = 1; i <= k; i++)
        {
            if (i == top.first) continue;
            int next = i;
            int nmult = top.second | (1<<(i-1));
            if (sol[next][nmult] > sol[top.first][top.second] + bests[top.first][necs[next]])
            {
                sol[next][nmult] = sol[top.first][top.second] + bests[top.first][necs[next]];
                q2.push(make_pair(next, nmult));
            }
        }
    }
    int minim = INF;
    for (int i = 0; i <= k; i++)
    {
        if (sol[i][(1<<k)-1] + bests[i][n] < minim)
            minim = sol[i][(1<<k)-1] + bests[i][n];
    }
    return minim;

}

int main()
{
    freopen("ubuntei.in", "r", stdin);
    freopen("ubuntei.out", "w", stdout);

    citire();
    for (int i = 0; i <= k; i++)
        dijkstra(necs[i], bests[i]);
    if (k == 0)
        printf("%d", bests[0][n]);
    else
        printf("%d", solve());

    return 0;
}