Cod sursa(job #1598708)

Utilizator usermeBogdan Cretu userme Data 13 februarie 2016 11:25:00
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.25 kb
#include <iostream>
#include <vector>
#include <queue>
#include <cstdio>
#include <algorithm>

const int nmax = 2001;
const int kmax = 16;
const int inf = 1 << 30;

using namespace std;

FILE *f=fopen("ubuntzei.in","r");
FILE *h=fopen("ubuntzei.out","w");

struct type{
    int c,d;
};

int best[1 << kmax][kmax], n, v[kmax+1], a[nmax][nmax], nod, k;

struct comp{
    int operator()(int x, int y) {
        return a[nod][x]>a[nod][y];
    }
};

vector <type> l[nmax];

priority_queue <int, vector <int>, comp> q;

void dijkstra() {
    int i, j, x;
    q.push(nod);
    for (i = 1; i <= n; ++i) {
        a[nod][i] = inf;
    }
    a[nod][nod]=0;
    while (!q.empty()) {
        x = q.top();
        q.pop();
        for (i = 0; i < l[x].size(); ++i) {
            j = l[x][i].d;
            if(a[nod][j] > a[nod][x] + l[x][i].c){
                a[nod][j] = a[nod][x] + l[x][i].c;
                q.push(j);
            }
        }
    }
}
int drum(int conf, int x) {
    if(best[conf][x] != 0)
        return best[conf][x];
    if(conf == 0)
        return 0;
    int i, j, p, val = inf, y;
    for (i = 0;i <= k; ++i) {
        if(i > 0) {
            if(conf & (1 << i)) {
                val = min(val, drum(conf ^ (1<<i), i) + a[v[x]][v[i]]);
            }
        }
        else {
            if(i == 0 && conf == 1) {
                val = a[v[x]][v[i]];
            }
        }
    }
    best[conf][x] = val;
    return best[conf][x];
}

int main() {
    int i, j, m, x, y, mini = inf;
    type aux;
    fscanf(f, "%d %d", &n, &m);
    fscanf(f, "%d", &k);
    for(i = 1; i <= k; ++i) {
        fscanf(f, "%d", &v[i]);
    }
    for(i = 1; i <= m; ++i) {
        fscanf(f, "%d %d %d", &x, &y, &aux.c);
        aux.d = y;
        l[x].push_back(aux);
        aux.d = x;
        l[y].push_back(aux);
    }
    nod = 1;
    dijkstra();
    if(k == 0) {
        fprintf(h, "%d", a[1][n]);
        return 0;
    }
    for(i = 1;i <= k; ++i) {
        nod = v[i];
        dijkstra();
    }
    v[0] = n;
    for(i = 1;i <= k; ++i) {
        x = drum(((1 << (k + 1)) - 1) ^ (1 << i), i) + a[1][v[i]];
        if(x < mini)
            mini = x;
    }
    fprintf(h, "%d",mini);
    return 0;
}