Cod sursa(job #1472829)

Utilizator TimitocArdelean Andrei Timotei Timitoc Data 17 august 2015 20:21:37
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.86 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>

#define MAXN 2011
#define MAXK 16
#define INF 0x4fffffff

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[1<<15][MAXK+1];
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 solve1() // using dijkstra, 75 solution TLE on rest
{
    for (int i = 0; i <= k+1; 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();
        if (top.first == k+1)
            return sol[k+1][(1<<k)-1];
        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));

                if (nmult == (1<<k)-1 && sol[k+1][(1<<k)-1] > sol[next][nmult] + bests[next][n])
                {
                    sol[k+1][(1<<k)-1] = sol[next][nmult] + bests[next][n];
                    q2.push(make_pair(k+1, (1<<k)-1));
                }
            }
        }
    }
    /*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 minim(int a, int b) {return a < b ? a : b;}
int solve() // using dynamic programming, 100 solution
{
    for (int i = 0; i < (1<<k); i++)
        for (int j = 0; j <= k; j++)
            sol[i][j] = INF;
    sol[0][0] = 0;
    for (int i = 1; i < (1<<k); i++)
    {
        for (int j = 1; j <= k; j++)
        {
            if (i & (1<<(j-1)))
            {
                int lasti = i - (1<<(j-1));
                for (int p = 0; p <= k; p++)
                    if (sol[lasti][p] != INF)
                        sol[i][j] = minim(sol[i][j], sol[lasti][p] + bests[p][necs[j]]);

            }
        }
    }
    int rez = INF;
    for (int i = 1; i <= k; i++)
        rez = minim(rez, sol[(1<<k)-1][i] + bests[i][n]);
    return rez;
}

int main()
{
    freopen("ubuntzei.in", "r", stdin);
    freopen("ubuntzei.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;
}