Cod sursa(job #1908589)

Utilizator CodrutLemeniCodrut Lemeni CodrutLemeni Data 7 martie 2017 09:33:14
Problema Ubuntzei Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.05 kb
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <string.h>
#include <queue>

using namespace std;

const int K = 18 ;
const int N = 2010 ;

class cmp{
public:

    bool operator()( pair<int , int> a , pair< int , int > b ){
        return a.second > b.second ;
    }

};

int matDist [ K ][ K ] ,dist [ N ] , viz [ N ];
int noNodes,noEdges , noImp , cImportant[ K ];

priority_queue < pair<int,int> , vector < pair <int ,int > > , cmp > que ;
vector < pair < int , int > > edges [ N ];
vector < pair < int , int > >::iterator it ;


void solveDijkstra ( int node ){
    static int i , vec ;

    memset ( viz , 0 , sizeof viz );
    for ( i = 1 ; i <= noNodes ; i ++ ){
        dist [ i ] = 1e8;
    }

    dist [ node ] = 0 ;

    que.push( make_pair(node , 0 ) );

    while ( !que.empty() ){

        while ( !que.empty() && viz [ que.top().first ] == 1 ){
            que.pop();
        }

        if ( que.empty() ){
            break ;
        }

        node = que.top().first ;
        viz [ node ] = 1 ;
        que.pop();

        for ( it = edges[ node ].begin() ; it != edges [ node ].end() ; it++ ){
            vec = it ->first ;
            if( viz[ vec ] ){
                continue ;
            }

            if ( dist [ vec ] > dist [ node ] + it->second  ){
                dist [ vec ] = dist [ node ] + it->second ;
                que.push( make_pair( vec , dist[ vec ] ) );
            }

        }

    }

}


int bestSol [ 1 << (K + 1) ][ K ];


int main(){
    int i , x , y , cost ,j , k ;

    freopen("ubuntzei.in","r",stdin);
    freopen("ubuntzei.out","w",stdout);

    scanf("%d%d",&noNodes , &noEdges );

    scanf("%d",&noImp);

    cImportant [ 0 ] = 1 ;
    cImportant [ noImp + 1 ] = noNodes ;
    for ( i = 1 ; i <= noImp ; i++ ){
        scanf("%d",&cImportant [ i ] );
    }
    noImp += 2 ;

    for ( i = 0 ; i < noEdges ; i ++ ){
        scanf("%d %d %d", &x ,&y ,&cost );
        edges [ x ].push_back( make_pair( y , cost ) );
        edges [ y ].push_back( make_pair( x , cost ) );

    }

    for( i = 0 ; i < noImp ; i++ ){
        solveDijkstra ( cImportant [ i ] );

        for ( j = 0 ; j < noImp ; j++ ){
            matDist [ i  ][ j ] = dist [ cImportant[j] ] ;
        }

    }

    for ( j = 0 ; j < 1<< (noImp + 1 ) ; j++ ){
        for ( i = 0 ; i < noImp ; i ++ ){
            bestSol [ j ] [ i ] = 1e9;
        }
    }
    bestSol [ 1 ][ 0 ] = 0 ;
    for ( j = 1 ; j < 1 << noImp ; j ++ ){
        for ( i = 0 ; i < noImp; i++ ){

            if ( bestSol [ j ][ i ] == 1e9 ){
                continue ;
            }

            for ( k = 0 ; k < noNodes ; k++ ){
                if( (1<<k) & j ){
                    continue ;
                }
                bestSol [ j + (1<<k) ][ k ] = min ( bestSol [ j + (1<<k) ][ k ] , bestSol[ j ][ i ] + matDist [ i ][ k ] );

            }

        }
    }

    printf("%d",bestSol [ (1 << noImp) -1  ][ noImp - 1 ] );

    return 0;
}