Cod sursa(job #1125482)

Utilizator antonioteoZait Teodor Antonio antonioteo Data 26 februarie 2014 17:54:15
Problema Ubuntzei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.04 kb
#include <queue>
#include <fstream>
#include <cstring>
#include <algorithm>
using namespace std;

ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");

#define INF 0x3f3f3f3f
#define NMAX 2001
#define KMAX 17

struct Nod {
	int u;
	int l;
	Nod *next;
};
Nod *v[NMAX];

int i, j, k, N, M, K;
int x, y, z;
int ans;

bool isK[NMAX];

void add(int i, int j, int k) {
	Nod *p = new Nod;
	p->u = j;
	p->l = k;
	p->next = v[i];
	v[i] = p;
}

int nod[KMAX];
int d[NMAX][NMAX];
int cost[KMAX][KMAX];
int dp[(1 << KMAX)][KMAX];

struct cmp {
    bool operator()(const int &a, const int &b) {
        if (d[i][a] > d[i][b]) return 1;
        return 0;
    }
};
 
priority_queue <int, vector <int>, cmp> Q;

int main() {
	fin >> N >> M >> K;
    isK[1] = isK[N] = true;
    for (i = 0; i < K; ++i) {
        fin >> nod[i];
        isK[nod[i]] = true;
    }
    for (i = 1; i <= M; ++i) {
        fin >> x >> y >> z;
        add(x, y, z);
        add(y, x, z);
    }
	nod[K] = 1;
    for (j = 0; j <= K; ++j) {
		i = nod[j];
        memset(d[i], INF, sizeof(d[i]));
        d[i][i] = 0;
        Q.push(i);
        while (!Q.empty()) {
            x = Q.top();
            for (Nod *it = v[x]; it; it = it->next) {
                if (d[i][x] + it->l < d[i][it->u]) {
                    d[i][it->u] = d[i][x] + it->l;
                    if (isK[i] && isK[it->u])
                        cost[i][it->u] = d[i][it->u];
                    Q.push(it->u);
                }
            }
            Q.pop();
        }
    }
	int lim = (1 << K);
	memset(dp, INF, sizeof(dp));
	for (i = 0; i < K; ++i) 
		dp[(1 << i)][i] = cost[1][nod[i]];
	for (i = 1; i <= lim; ++i) {
		for (j = 0; j < K; ++j) {
			if (i & (1 << j)) {
				for (k = 0; k < K; ++k)
					if (k != j && (i & (1 << k)))
						dp[i][j] = min(dp[i][j], dp[i ^ (1 << j)][k] + cost[nod[k]][nod[j]]);
			}
		}
	}
	ans = INF;
	for (i = 0; i < K; ++i)
		ans = min(ans, dp[lim - 1][i] + cost[nod[i]][N]);
	fout << ans << '\n';
	return 0;
}