Cod sursa(job #2797824)

Utilizator LucaMihaiLM10Luca Ilie LucaMihaiLM10 Data 10 noiembrie 2021 17:24:00
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.72 kb
#include <stdio.h>
#include <queue>
#include <vector>

#define MAX_N 2000
#define MAX_K 15
#define MAX_COST 2100000000

using namespace std;

struct muchie {
    int nod, cost;
};

struct node {
    int nod, d;
    bool operator < (const node &aux) const {
        return d > aux.d;
    }
};

int dist[MAX_K][MAX_N], viz[MAX_N], u[MAX_N], costMin[1 << MAX_K][MAX_K];
vector <muchie> muchii[MAX_N];
priority_queue <node> pq;

int main() {
    FILE *fin, *fout;
    int n, m, k, x, y, minCost, next, c, mask, b1, i, j;
    struct node crt;

    fin = fopen( "ubuntzei.in", "r" );
    fscanf( fin, "%d%d%d", &n, &m, &k );
    for ( i = 0; i < k; i++ ) {
        fscanf( fin, "%d", &u[i] );
        u[i]--;
    }
    for ( i = 0; i < m; i++ ) {
        fscanf( fin, "%d%d%d", &x, &y, &c );
        x--;
        y--;
        muchii[x].push_back( { y, c } );
        muchii[y].push_back( { x, c } );
    }
    fclose( fin );

    if ( k == 0 ) {
        u[0] = 0;
        k = 1;
    }
    for ( i = 0; i < k; i++ ) {
        for ( j = 0; j < n; j++ ) {
            dist[i][j] = -1;
            viz[j] = 0;
        }

        pq.push( { u[i], 0 } );
        while ( !pq.empty() ) {
            crt = pq.top();
            pq.pop();
            if ( viz[crt.nod] == 0 ) {
                viz[crt.nod] = 1;
                dist[i][crt.nod] = crt.d;
                for ( j = 0; j < muchii[crt.nod].size(); j++ ) {
                    next = muchii[crt.nod][j].nod;
                    c = muchii[crt.nod][j].cost;
                    if ( dist[i][next] == -1 || dist[i][crt.nod] + c < dist[i][next] ) {
                        dist[i][next] = dist[i][crt.nod] + c;
                        pq.push( { next, dist[i][crt.nod] + c } );
                    }
                }
            }
        }
    }

    for ( mask = 1; mask < (1 << k); mask++ ) {
        b1 = 0;
        for ( i = 0; i < k; i++ ) {
            if ( (mask >> i) & 1 )
                b1++;
        }
        for ( i = 0; i < k; i++ ) {
            if ( b1 == 1 )
                costMin[mask][i] = dist[i][0];
            else
                costMin[mask][i] = MAX_COST;
            if ( (mask >> i) & 1 ) {
                for ( j = 0; j < k; j++ ) {
                    if ( i != j && ((mask >> j) & 1) )
                        costMin[mask][i] = min( costMin[mask][i], costMin[mask - (1 << i)][j] + dist[i][u[j]] );
                }
            }
        }
    }

    minCost = MAX_COST;
    for ( i = 0; i < k; i++ )
        minCost = min( minCost, costMin[(1 << k) - 1][i] + dist[i][n - 1] );

    fout = fopen( "ubuntzei.out", "w" );
    fprintf( fout, "%d", minCost );
    fclose( fout );

    return 0;
}