Cod sursa(job #1554067)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 20 decembrie 2015 21:04:26
Problema Drumuri minime Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.8 kb
#include <bits/stdc++.h>

using namespace std;

const int kMaxN = 1500;
const int kMaxM = 2500;
const int kMod = 104659;
const int NIL = -1;
const double kEps = 1e-12;

struct Edge {
  int v, next;
  double cost;
};

Edge l[2 * kMaxM];
int adj[kMaxN];
double minCost[kMaxN];

int solutionCount[kMaxN];

struct costCmp {
  bool operator () (const int &A, const int &B) {
    return minCost[A] > minCost[B];
  }
};

priority_queue <int, vector <int>, costCmp> Q;

void addEdge(const int &u, const int &v, const double &cost, const int &pos) {
  l[pos].v = v;
  l[pos].cost = cost;
  l[pos].next = adj[u];
  adj[u] = pos;
}

int main(void) {
  ifstream in("dmin.in");
  ofstream out("dmin.out");
  int N, M;
  int u, v, c;

  in >> N >> M;
  for (int i = 0; i < N; i++) {
    adj[i] = NIL;
  }
  for (int i = 0; i < M; i++) {
    in >> u >> v >> c;
    double cost = log(static_cast <double> (c));
    addEdge(u - 1, v - 1, cost, 2 * i);
    addEdge(v - 1, u - 1, cost, 2 * i + 1);
  }
  in.close();

  for (int i = 1; i < N; i++) {
    minCost[i] = numeric_limits <double> :: max();
  }

  solutionCount[0] = 1;
  Q.push(0);
  do {
      u = Q.top();
      Q.pop();
      for (int i = adj[u]; i != NIL; i = l[i].next) {
        int v = l[i].v;
        if (minCost[v] - (minCost[u] + l[i].cost) > kEps) {
          minCost[v] = minCost[u] + l[i].cost;
          solutionCount[v] = solutionCount[u];
          Q.push(v);
        } else if (fabs(minCost[v] - (minCost[u] + l[i].cost)) <= kEps) {
          solutionCount[v] += solutionCount[u];
          solutionCount[v] -= kMod & -(solutionCount[v] >= kMod);
        }
      }
  } while (!Q.empty());

  for (int i = 1; i < N; i++) {
    out << solutionCount[i] << " \n"[i == N - 1];
  }
  out.close();
  return 0;
}