Pagini recente » Istoria paginii utilizator/andreikatsuki | Cod sursa (job #3360190)
/// Drumuri minime infoarena
#include <fstream>
#include <vector>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std;
ifstream fin("dmin.in");
ofstream fout("dmin.out");
const double EPS = 1e-9;
const int MOD = 104659;
vector<int> numOfMinPathsToEachPlanet(int n, vector<vector<pair<int, double>>> edges)
{
vector<double> minDist(n, 0);
priority_queue<pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>>> pq;
vector<int> cnt(n, 0); /// cnt[i] = number of min paths from node 0 to node i
pq.push({0, 0});
while (!pq.empty())
{
auto [cost, node] = pq.top();
pq.pop();
if (abs(minDist[node] - cost) > EPS) { continue; }
for (auto & [ad, cost_ad] : edges[node])
{
/// if we discovered a better/ new path, we replace minDist and the count of min paths
if ((minDist[ad] < EPS) || (minDist[ad] - EPS > cost + cost_ad)) /// with int: (minDist[ad] == 0) || (minDist[ad] > cost + cost_ad)
{
minDist[ad] = cost + cost_ad;
pq.push({minDist[ad], ad});
if (node == 0)
{
cnt[ad] = 1;
}
else
{
cnt[ad] = cnt[node];
}
}
/// if we discovered another path of the same optimal length, we update the count
else if (abs(minDist[ad] - (cost + cost_ad)) < EPS)
{
if (node == 0)
{
cnt[ad]++;
}
else
{
cnt[ad] += cnt[node];
}
}
}
}
return cnt;
}
int main()
{
int n, m;
fin >> n >> m;
vector<vector<pair<int, double>>> edges(n); /// !!! log(c) is double
for (int i = 1; i <= m; i++)
{
int x, y, c;
fin >> x >> y >> c;
edges[--x].push_back({--y, log(c)});
}
fin.close();
vector<int> ans = numOfMinPathsToEachPlanet(n, edges);
for (int i = 1; i < n; i++)
{
fout << ans[i] << ' ';
}
fout.close();
return 0;
}