Cod sursa(job #1612328)

Utilizator LolkekzorChiorean Tudor Lolkekzor Data 24 februarie 2016 20:03:03
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.28 kb
#include <fstream>
#include <list>
#include <vector>
#include <queue>
#define INF 2000000000
#define node first
#define len second
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");

int n, m, k, x, y, c, i, j, p, crt, nrUbuntz;
int roadLength[2010], isUbuntzel[2010];
int hamiltonLength[20][20], dynProg[1 << 18][18];
vector<int> ubuntzei;
list<pair<int, int> > graph[2010];
queue<int> Q;

int main() {
    fin>>n>>m>>k;

    ubuntzei.push_back(0); /// FILLER, NOT USED
    ubuntzei.push_back(1); /// START TOWN
    for ( i = 1 ; i <= k ; i++ ) {
        fin>>x;
        isUbuntzel[x] = i;
        ubuntzei.push_back(x); /// INTERMEDIATE TOWNS
    }
    ubuntzei.push_back(n); /// END TOWN

    for ( i = 1 ; i <= m ; i++ ) {
        fin>>x>>y>>c;
        graph[x].push_back(make_pair(y, c));
        graph[y].push_back(make_pair(x, c));
    }

    for ( i = 1 ; i < ubuntzei.size() ; i++) {
        for ( j = 1 ; j <= n ; j++ )
            roadLength[j] = INF;

        Q.push(ubuntzei[i]);
        roadLength[ubuntzei[i]] = 0;
        while (!Q.empty()) {
            crt = Q.front(); Q.pop();
            for (list<pair<int, int> >::iterator it = graph[crt].begin() ; it != graph[crt].end() ; it++) {
                if (roadLength[crt] + it->len < roadLength[it->node]) {
                    Q.push(it->node);
                    roadLength[it->node] = roadLength[crt] + it->len;
                }
            }
        }

        for ( j = 1 ; j < ubuntzei.size() ; j++ )
            hamiltonLength[i - 1][j - 1] = roadLength[ubuntzei[j]];
    }

    nrUbuntz = k + 2;
    for ( i = 1 ; i <= ( 1 << nrUbuntz ) - 1 ; i++ )
        for ( j = 0 ; j <= nrUbuntz ; j++ )
            dynProg[i][j] = INF;

    dynProg[1][0] = 0;
    for ( i = 1 ; i <= ( 1 << nrUbuntz ) - 1 ; i++ ) {
        for ( j = 0 ; j < nrUbuntz ; j++ ) {
            if ( ( 1 << j ) & i ) {
                for ( p = 0 ; p < nrUbuntz ; p++ ) {
                    if ( p != j && ( ( 1 << p ) & i ) ) {
                        dynProg[i][j] = min(dynProg[i][j], dynProg[i ^ (1 << j)][p] + hamiltonLength[p][j]);
                    }
                }
            }
        }
    }

    fout<<dynProg[( 1 << nrUbuntz ) - 1][nrUbuntz - 1];

return 0;
}