Cod sursa(job #2404652)

Utilizator borcanirobertBorcani Robert borcanirobert Data 13 aprilie 2019 11:16:11
Problema Pitici Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.01 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <stack>
using namespace std;

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

using VI  = vector<int>;
using VVI = vector<VI>;
using VB  = vector<bool>;
using PII = pair<int, int>;
using VP  = vector<PII>;
using VVP = vector<VP>;

const int Inf = 0x3f3f3f3f;

struct Pair{
	Pair(int node, int cost, int c0)
		: node{node}, cost{cost}, c0{c0}
	{}
	
	int node, cost, c0;
	
	bool operator < (const Pair& p) const
	{
		return cost > p.cost;
	}
};

int N, M, K;
VVP G, RG;
VI D;
VI nodes;
VB vis;
stack<int> st;

void ReadData();
void SortNodes();
void DFS_TopSort(int node);
void Solve();
void CalcCosts();

int main()
{
	ReadData();
	SortNodes();
	Solve();
	
	fin.close();
	fout.close();
	return 0;
}

void ReadData()
{
	fin >> N >> M >> K;
	G = RG = VVP(N + 1);
	
	int x, y, w;
	while (M--)
	{
		fin >> x >> y >> w;

		G[x].emplace_back(y, w);
		RG[y].emplace_back(x, w);
	}
}

void SortNodes()
{
	vis = VB(N + 1);
	for (int i = 1; i <= N; ++i)
		if (!vis[i])
			DFS_TopSort(i);
	
	while (!st.empty())
	{
		nodes.emplace_back(st.top());
		st.pop();
	}
}

void DFS_TopSort(int node)
{
	vis[node] = true;
	
	for (const auto& v : G[node])
		if (!vis[v.first])
			DFS_TopSort(v.first);
	
	st.push(node);
}

void Solve()
{
	CalcCosts();
	
	/*for (int i = 1; i <= N; ++i)
		cout << i << ' ' << D[i] << '\n';
	cin.get();		*/
	
	priority_queue<Pair> Q;
	Q.emplace(1, D[1], 0);
	
	int cnt{0};
	while (cnt < K)
	{
		int node = Q.top().node;
		int cost = Q.top().cost;
		int c0   = Q.top().c0;
		Q.pop();
		
		//cout << node << ' ' << cost; cin.get();
		
		if (node == N)
		{
			fout << cost << ' ';
			++cnt;
			
			continue;
		}
		
		for (const auto& v : G[node])
		{
			Q.emplace(v.first, c0 + v.second + D[v.first], c0 + v.second);
		}
	}
}

void CalcCosts()
{
	D = VI(N + 1, Inf);
	D[N] = 0;
	
	for (int i = static_cast<int>(nodes.size()); i >= 0; --i)
		for (const auto& v : RG[nodes[i]])
			if (D[v.first] > D[nodes[i]] + v.second)
				D[v.first] = D[nodes[i]] + v.second;
}