Cod sursa(job #2083899)

Utilizator netfreeAndrei Muntean netfree Data 8 decembrie 2017 12:02:06
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2 kb
#include <bits/stdc++.h>
#define pp pair<int, int>
#define x first
#define y second

using namespace std;

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

const int N_MAX = 2000 + 5;
const int K_MAX = 15 + 5;
const int inf = 0x3f3f3f3f;

int n, m, k;

vector<pp> vec[N_MAX];
int special[K_MAX];
int cst[K_MAX][N_MAX];
int dp[(1 << 18)][K_MAX];
map<int, int> ubuntzel;
priority_queue <pp, vector<pp>, greater<pp> > q;
int temp[N_MAX];

void dijikstra(int u_ord){
    int nod = special[u_ord];
    memset(temp, inf, sizeof(temp));
    q.push({nod, 0});
    temp[nod] = 0;
    while(q.size()){
        int new_nod = q.top().x;
        int total_cost = q.top().y;
        q.pop();

        for(auto v : vec[new_nod]){
            if(temp[v.x] > temp[new_nod] + v.y){
                temp[v.x] = temp[new_nod] + v.y;
                q.push({v.x, temp[v.x]});
            }
        }
    }

    for(int i = 0; i<=k; ++i)
        cst[u_ord][i] = temp[special[i]];
}

bool isbit(int mask, int i){
    return (mask & (1 << i));
}

void hamilton(){
    memset(dp, inf, sizeof(dp));

    dp[1][0] = 0;

    for(int mask = 1; mask < (1<<k); ++mask){
        for(int i = 0; i<k; ++i){
            if(isbit(mask, i)){
                for(int j = 0; j<k; ++j){
                    if(!isbit(mask, j)){
                        dp[mask + (1<<j)][j] = min( dp[mask][i] + cst[i][j] , dp[mask + (1<<j)][j] );
                    }
                }
            }
        }
    }
}

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

    memset(cst, inf, sizeof(cst));

    special[0] = 1;
    special[k+1] = n;

    for(int i = 1; i<=k; ++i)
        fin >> special[i];

    k ++;

    while(m--){
        int a, b, c;
        fin >> a >> b >> c;
        vec[a].push_back({b,c});
        vec[b].push_back({a,c});
    }

    for(int i = 0; i<=k; ++i)
        dijikstra(i);



   ++k;
    hamilton();



    fout << dp[(1<<k)-1][k-1];

    return 0;
}