Cod sursa(job #1551274)

Utilizator cristian.caldareaCaldarea Cristian Daniel cristian.caldarea Data 15 decembrie 2015 17:09:45
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.01 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

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

using VI = vector<int>;
using VVI = vector<VI>;


struct Pair {
	int dist, nod;

	bool operator < (const Pair& p) const
	{
		return dist > p.dist;
	}
};

const int Inf = 0x3f3f3f3f;

int n, m, K, sol = Inf;
VVI D, dp;
vector<vector<pair<int, int>>> G;
VI C, d;

void Read();
void Dijkstra(int S, VI& d);
int main()
{
    Read();
    Dijkstra(1, d);
    if (K == 0)
	{
		fout << d[n] << '\n';

		fout.close();
		return 0;
	}

	for (int i = 0; i < K; ++i)
		Dijkstra(C[i], D[i]);

	for (int j = 0; j < K; ++j)
		dp[1 << j][j] = d[C[j]];

    for ( int i = 1; i < (1 << K); i++)
        for ( int j = 0; j < K; j++ )
            if (  i & ( 1 << j ) )
                for ( int k = 0; k < K; k++ )
                    if ( i & ( 1 << k ) )
                    {
                        dp[i][j] = min(dp[i][j], dp[i ^ (1 << j)][k] + D[k][C[j]]);
                    }

	for (int i = 0; i < K; ++i)
		sol = min(sol, dp[(1 << K) - 1][i] + D[i][n]);

	fout << sol << '\n';

    return 0;
}

void Read()
{
    fin >> n >> m >> K;
	G = vector<vector<pair<int,int>>>(n + 1);
	C = VI(K);  D = VVI(K);
	dp = VVI(1 << K, VI(K, Inf));

	for (int i = 0; i < K; ++i)
		fin >> C[i];

	for (int i = 1, x, y, w; i <= m; ++i)
	{
		fin >> x >> y >> w;
		G[x].push_back({y, w});
		G[y].push_back({x, w});
	}
	fin.close();

}

void Dijkstra(int S, VI& d)
{
    priority_queue<Pair> Q;
	d = VI(n + 1, Inf);
	d[S] = 0;
    Q.push({0, S});
    int x, y, z, dx;
	while( !Q.empty() )
    {
        x = Q.top().nod;
        dx = Q.top().dist;
        Q.pop();
        if ( d[x] < dx )
            continue;
        for ( auto w : G[x] )
        {
            y = w.first;
            z = w.second;
            if ( d[x] + z < d[y] )
            {
                d[y] = d[x] + z;
				Q.push({d[y], y});
            }
        }
    }

}