Cod sursa(job #595007)

Utilizator nandoLicker Nandor nando Data 10 iunie 2011 19:32:41
Problema Ubuntzei Scor 15
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.67 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <bitset>
#include <queue>
using namespace std;

#define min(a, b) (((a) < (b)) ? (a) : (b))

#define MAXN 2010
#define MAXK 18
#define INF 0x3f3f3f3f

#define node first
#define dist second

int n, m, k;
int c[MAXK];
int d[MAXK][MAXN], src[MAXN];
int cost[1 << MAXK][MAXK];

vector <pair <int, int> > g[MAXN];
typedef vector <pair <int, int> >::iterator iter;

void dijkstra (int source, int* dest)
{
    for (int i = 1; i <= n; ++i) {
        dest[i] = INF;
    }

    dest[source] = 0;

    bitset <MAXN> viz;
    priority_queue <pair <int, int> > q;
    q.push (make_pair (0, source));
    viz[source] = true;

    while (!q.empty ()) {
        int nd = q.top ().second;
        q.pop ();

        for (iter it = g[nd].begin (); it != g[nd].end (); ++it) {
            if (dest[nd] + it->dist > dest[it->node])
                continue;

            dest[it->node] = dest[nd] + it->dist;
            if (!viz[it->node]) {
                q.push (make_pair (-dest[it->node], it->node));
                viz[it->node] = true;
            }
        }
        viz[nd] = false;
    }
}

int hamilton ()
{
    for (int i = 1; i < (1 << k); ++i) {
        if (i & (i - 1) == 0) {
            for (int j = 0; j < k; ++j) {
                if (i == (1 << j)) {
                    cost[i][j] = src[c[j]];
                }
            }
            continue;
        }

        for (int j = 0; j < k; ++j) {
            cost[i][j] = INF;
            if (i & (1 << j)) {
                for (int l = 0; l < k; ++l) {
                    if (l != j && (i & (1 << l))) {
                        cost[i][j] = min (cost[i][j], cost[i - (1 << j)][l] + d[l][c[j]]);
                    }
                }
            }
        }
    }

    int res = INF;
    for (int i = 0; i < k; ++i) {
		res = min (res, cost[(1 << k) - 1][i] + d[i][n]);
    }
    return res;
}

int main ()
{
    FILE* fin = fopen ("ubuntzei.in", "r");
    FILE* fout = fopen ("ubuntzei.out", "w");

    fscanf (fin, "%d %d\n%d", &n, &m, &k);

    for (int i = 0; i < k; ++i) {
        fscanf (fin, "%d", &c[i]);
    }

    for (int i = 1; i <= m; ++i) {
        int x, y, z;
        fscanf (fin, "%d %d %d\n", &x, &y, &z);

        g[x].push_back (make_pair (y, z));
        g[y].push_back (make_pair (x, z));
    }

    dijkstra (1, src);

    if (k == 0) {
        printf ("%d" , src[n]);
    } else {
        for (int i = 0; i < k; ++i) {
            dijkstra (c[i], d[i]);
        }

        fprintf (fout, "%d\n", hamilton ());
    }

    fclose (fin);
    fclose (fout);
    return 0;
}