Cod sursa(job #1643685)

Utilizator TimitocArdelean Andrei Timotei Timitoc Data 9 martie 2016 19:48:31
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.18 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#define MAXN 2016
#define MAXK 20
#define INF 0x7fffffff

using namespace std;

int n, m, k;
struct elem
{
    int nod, cost;
    elem(int nod = 0, int cost = 0) : nod(nod), cost(cost) { }
    bool operator()(elem a, elem b)
    {
    	return a.cost > b.cost;
    }
};
vector<elem> graf[MAXN];
priority_queue<elem, vector<elem>, elem> q;
int priet[MAXK], cost[MAXK][MAXN];
int din[MAXK][(1<<17)+50];

void citire()
{
    scanf("%d %d\n%d", &n, &m, &k);
    priet[0] = 1;
	for (int i = 1; i <= k; i++)
		scanf("%d", &priet[i]);
	priet[++k] = n;
	for (int i = 1; i <= m; i++) {
		int x, y, z;
        scanf("%d %d %d", &x, &y, &z);
        graf[x].push_back(elem(y, z));
        graf[y].push_back(elem(x, z));
	}
	for (int i = 0; i <= k+1; i++)
        for (int j = 1; j <= n; j++)
			cost[i][j] = INF;
}

void dijkstra(int nod, int best[MAXN])
{
    while (!q.empty()) q.pop();
    best[nod] = 0;
    for (q.push(elem(nod, 0)); !q.empty(); q.pop()) {
        elem top = q.top();
        int crt = top.nod;
        for (int i = 0, t = graf[crt].size(); i < t; i++) {
			int y = graf[crt][i].nod;
            if (top.cost + graf[crt][i].cost < best[y]) {
				best[y] = top.cost + graf[crt][i].cost;
				q.push(elem(y, best[y]));
            }
        }
    }
}

void debug()
{
    for (int i = 0; i <= k; i++, printf("\n")) {
        int nod = priet[i];
        printf("%d:\t", nod);
        for (int j = 1; j <= n; j++)
			printf("%d ", cost[i][j]);
    }
}

int solve(int nod, int mask)
{
	if (din[nod][mask] != -1)
		return din[nod][mask];
	din[nod][mask] = INF>>1;
    for (int i = 0; i <= k; i++) {
        if (i!= nod && (mask & (1<<i))) {
            din[nod][mask] = std::min(din[nod][mask], cost[nod][priet[i]] + solve(i, mask^(1<<nod)));
        }
    }
    return din[nod][mask];
}

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

    citire();
    for (int i = 0; i <= k; i++)
        dijkstra(priet[i], cost[i]);
	//debug();
	for (int i = 0; i <= k; i++)
        for (int j = 0; j < (1<<(k+1)); j++)
            din[i][j] = -1;
	din[0][1] = 0;
    printf("%d", solve(k, (1<<(k+1))-1));

    return 0;
}