Cod sursa(job #1774926)

Utilizator cristian.caldareaCaldarea Cristian Daniel cristian.caldarea Data 9 octombrie 2016 16:52:46
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.06 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>;
const int Inf = 0x3f3f3f3f;


struct Node {
	int dist, nod;

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



int n, m, u, ans = Inf, f;
VI p, d;
vector<VI> D, dp;
vector<vector<pair<int, int>>> G;
priority_queue<Node> Q;


void Read();
void Dijkstra(int S, VI& d);

int main()
{
    Read();

    Dijkstra(1, d);

        if ( u == 0 )
	{
		fout << d[n] << '\n';

		fout.close();
		return 0;
	}


	for (int i = 0; i < u; ++i)
		Dijkstra(p[i], D[i]);

	for (int i = 0; i < u; i++)
        dp[1 << i][i] = d[p[i]];

    for ( int i = 1; i <= f; i++)
        for ( int j = 0; j < u; j++ )
            if ( i & (1 << j) )
                for ( int k = 0; k < u; k++ )
                    if ( !(i & ( 1 << k )) )
                        dp[i | (1 << k)][k] = min(dp[i | (1 << k)][k], dp[i][j] + D[j][p[k]]);

    for (int i = 0; i < u; ++i)
		ans = min(ans, dp[f][i] + D[i][n]);

	fout << ans << '\n';
    fin.close();
    fout.close();
    return 0;
}
void Read()
{
    fin >> n >> m >> u;
    f = (1 << u) - 1;
	p = VI(u);
    D = vector<VI>(u);
	dp = vector<VI>(f + 1, VI(u, Inf));
    G = vector<vector<pair<int,int>>>(n + 1);

	for (int i = 0; i < u; ++i)
		fin >> p[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});
	}

}

void Dijkstra(int S, VI& d)
{
    d = VI(n + 1, Inf);
	d[S] = 0;
    Q.push({0, S});

    int x, y, dx, dy;

    while ( !Q.empty() )
    {
        x = Q.top().nod;
        dx = Q.top().dist;
        Q.pop();

        if ( dx > d[x] )
            continue;

        for ( auto z : G[x] )
        {
            y = z.first;
            dy = z.second;

            if ( d[y] > dx + dy )
            {
                d[y] = dx + dy;
                Q.push({d[y], y});
            }
        }
    }
}