Cod sursa(job #1125614)

Utilizator antonioteoZait Teodor Antonio antonioteo Data 26 februarie 2014 18:42:02
Problema Ubuntzei Scor 35
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.23 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, lim;
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);
    }
    for (j = -1; j < K; ++j) {
		if (j == -1) i = 1;
        else
			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();
        }
    }
    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 && cost[nod[k]][nod[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;
}