Cod sursa(job #1694981)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 26 aprilie 2016 13:22:01
Problema Tunelul groazei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.61 kb
#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 255;
const double EPS = 1e-6;

int degree[MAX_N];
double A[MAX_N][MAX_N + 1];
int edgeCount[MAX_N][MAX_N];
double ret[MAX_N];

void echelonForm(const int n) {
  double tmp[MAX_N + 1];
  int i = 0, j = 0;
  while (i < n && j < n) {
    int k = i;
    while (k < n && fabs(A[k][j]) <= EPS)
      ++ k;
    if (k != n) {
      memmove(tmp, A[k], 8 * (n + 1));
      memmove(A[k], A[i], 8 * (n + 1));
      memmove(A[i], tmp, 8 * (n + 1));
      for (k = n; k >= j; -- k)
        A[i][k] /= A[i][j];
      for (k = i + 1; k < n; ++ k) {
        for (int q = n; q >= j; -- q)
          A[k][q] -= A[k][j] * A[i][q];
      }
      ++ i;
    }
    ++ j;
  }
}

int main() {
  ifstream fin("tunel.in");
  ofstream fout("tunel.out");
  fin.tie(0);
  ios_base::sync_with_stdio(0);

  int n, m; fin >> n >> m;
  
  for (int i = 0; i < m; ++ i) {
    int u, v, delta; fin >> u >> v >> delta; -- u; -- v;
    ++ edgeCount[u][v]; ++ edgeCount[v][u];
    A[v][n] += delta; A[u][n] += delta;
  }

  for (int i = 0; i < n - 1; ++ i) {
    int degree = 0;
    for (int j = 0; j < n; ++ j)
      degree += edgeCount[i][j];
    for (int j = 0; j < n - 1; ++ j)
        A[i][j] = -1.0 * edgeCount[i][j] / degree;
    A[i][i] = 1.0;
    A[i][n] /= degree;
  }
  A[n - 1][n - 1] = A[n - 1][n] = 1.0;
  
  echelonForm(n);

  for (int i = n - 1; i >= 0; -- i) {
    int j = 0;
    while (fabs(A[i][j]) <= EPS)
      ++ j;
    ret[j] = A[i][n];
    for (int k = j + 1; k < n; ++ k)
      ret[j] -= ret[k] * A[i][k];
  }

  fout << fixed << setprecision(6) << ret[0] << '\n';
  fout.close();
  
  return 0;
}