Cod sursa(job #1761696)

Utilizator BrandonChris Luntraru Brandon Data 22 septembrie 2016 18:47:09
Problema Tunelul groazei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.94 kb
#include <fstream>
#include <vector>

#define Pe pair <int, double>
#define m_p make_pair
#define fi first
#define se second
using namespace std;

ifstream cin("tunel.in");
ofstream cout("tunel.out");

const int MaxN = 260;
const double Eps = 1e-4;

vector <Pe> G[MaxN];
int n, m;
double mat[MaxN][MaxN], d[MaxN];

inline void SwapLine(double a[MaxN], double b[MaxN]) {
  for (int i = 1; i <= n; ++i) {
    swap(a[i], b[i]);
  }
}

inline void AddLine(double a[MaxN], double b[MaxN], double coef) {
  for (int i = 1; i <= n; ++i) {
    b[i] += a[i] * coef;
  }
}

inline bool IsNull(double x) {
  return x < Eps and x > -Eps;
}

void Gauss() {
  int CurrLin = 1;
  for (int CurrCol = 1; CurrCol < n; ++CurrCol) {
    if (CurrLin > n) {
      break;
    }

    if (IsNull(mat[CurrLin][CurrCol])) {
      for (int i = CurrLin + 1; i < n; ++i) {
        if (!IsNull(mat[i][CurrCol])) {
          SwapLine(mat[CurrLin], mat[i]);
          break;
        }
      }

      if (IsNull(mat[CurrLin][CurrCol])) {
        continue;
      }
    }

    for (int i = 1; i < n; ++i) {
      if (i == CurrLin) {
        continue;
      }

      AddLine(mat[CurrLin], mat[i], -(mat[i][CurrCol] / mat[CurrLin][CurrCol]));
    }

    ++CurrLin;
  }

  CurrLin = 1;
  for (int CurrCol = 1; CurrCol < n; ++CurrCol) {
    if (!IsNull(mat[CurrLin][CurrCol])) {
      d[CurrCol] = mat[CurrLin][n] / mat[CurrLin][CurrCol];
      ++CurrLin;
    }
  }
}

int main() {
  cin >> n >> m;
  for (int i = 1; i <= m; ++i) {
    int a, b, c;
    cin >> a >> b >> c;
    G[a].push_back(m_p(b, c));
    G[b].push_back(m_p(a, c));
  }

  for (int i = 1; i < n; ++i) {
    double probab = double (1.0 / G[i].size());
    mat[i][i] = 1;
    for (auto it: G[i]) {
      mat[i][n] += it.se * probab;
      if (it.fi != n) {
        mat[i][it.fi] -= probab;
      }
    }
  }

  Gauss();

  cout << d[1] << '\n';
  return 0;
}