Cod sursa(job #2708479)

Utilizator WilIiamperWilliam Damian Balint WilIiamper Data 18 februarie 2021 19:47:32
Problema Ubuntzei Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.4 kb
#include <fstream>
#include <vector>
#include <queue>

#define infinite 1500000000

using namespace std;

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

int n, m, k, ans;

int c[17];

typedef struct {
    int to;
    int len;
} edge;

edge make_edge ( int to, int len ) {
    edge e;
    e.to = to;
    e.len = len;
    return e;
}

vector < edge > G[ 2001 ];
int a[ 17 ][ 17 ];
bool inQueue[2001];

int dist[ 2001 ];

bool vis[17];
void Back ( int l, int last, int len ) {

    //fout << l << " " << last << " " << len << "\n";

    if ( len > ans )
        return;

    if ( l > k ) {
        if ( len + a[last][k+1] < ans )
            ans = len + a[last][k+1];
        return;
    }

    for ( int i = 1; i <= k; i++ ) {
        if ( !vis[i] ) {
            vis[i] = true;
            Back( l+1, i, len + a[last][i] );
            vis[i] = false;
        }
    }
}

void BellmanFord () {

    queue <int> Q;
    for ( int i = 0; i <= k; i++ ) {

        for ( int j = 1; j <= n; j++ )
            dist[j] = infinite;

        Q.push( c[i] );
        dist[ c[i] ] = 0;
        inQueue[ c[i] ] = true;

        while ( !Q.empty() ) {

            int node = Q.front();
            Q.pop();
            inQueue[ node ] = false;

            for ( unsigned int l = 0; l < G[node].size(); l++ ) {

                edge e = G[node][l];
                if ( dist[ node ] + e.len < dist[ e.to ] ) {

                    dist[ e.to ] = dist[node] + e.len;
                    if ( !inQueue[ e.to ] ) {
                        Q.push( e.to );
                        inQueue[ e.to ] = true;
                    }
                }
            }
        }

        for ( int j = 0; j <= k+1; j++ ) {
            a[ i ][ j ] = dist[ c[j] ];
            //fout << a[ i ][ j ] << " ";
        }
        //fout << "\n";
    }
}

void Solve () {
    BellmanFord();

    ans = infinite;
    Back( 1, 0, 0 );

    fout << ans;
}

void read () {

    fin >> n >> m;
    fin >> k;

    for ( int i = 1; i <= k; i++ )
        fin >> c[i];
    c[0] = 1;
    c[ k+1 ] = n;

    int from, to, len;
    for ( int i = 1; i <= m; i++ ) {
        fin >> from >> to >> len;
        G[from].push_back( make_edge( to, len ) );
        G[to].push_back ( make_edge( from, len) );
    }
}

int main()
{
    read();
    Solve();
    return 0;
}