Cod sursa(job #1744071)

Utilizator hrazvanHarsan Razvan hrazvan Data 19 august 2016 11:43:08
Problema Flux Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.29 kb
#include <cstdio>
#include <cstring>
#define MAXN 100
#define MAXM 5000
#define INF 9000000000000000.0
#define EPS 0.0000001
int ut[MAXN], nxt[2 * MAXM], nd[2 * MAXM], cpc[2 * MAXM], dr;
double pt[MAXN];
double gauss[MAXN][MAXN];
int grad[MAXN];

inline double myabs(double x){
  return x < 0 ? -x : x;
}

inline void add(int x, int y, int z){
  nd[dr] = y;
  nxt[dr] = ut[x];
  cpc[dr] = z;
  ut[x] = dr;
  dr++;
}

inline int cmp(double x, double y){
  if(x - y > EPS)
    return 1;
  if(y - x > EPS)
    return -1;
  return 0;
}

char tr[MAXN];

int dfs(int x){
  tr[x] = 1;
  int poz, mx = x;
  poz = ut[x];
  while(poz != -1){
    if(!tr[nd[poz]]){
      x = dfs(nd[poz]);
      if(x > mx)
        mx = x;
    }
    poz = nxt[poz];
  }
  return mx;
}

int main(){
  FILE *in = fopen("flux.in", "r");
  int n, m, i, j, k, x, y, z, poz;
  fscanf(in, "%d%d", &n, &m);
  memset(ut, -1, sizeof ut);
  for(i = 0; i < m; i++){
    fscanf(in, "%d%d%d", &x, &y, &z);
    x--;  y--;
    grad[x]++;  grad[y]++;
    add(x, y, z);
    add(y, x, z);
  }
  fclose(in);
  //init_gauss
  for(i = 1; i < n; i++){
    if(grad[i] != 0){
      poz = ut[i];
      while(poz != -1){
        gauss[i][i]++;
        gauss[i][nd[poz]]--;
        poz = nxt[poz];
      }
    }
  }
  //solve_gauss
  for(i = 1; i < n; i++){
    if(grad[i] != 0){
      for(j = i + 1; j < n; j++){
        if(grad[j] != 0){
          for(k = i + 1; k < n; k++)
            gauss[j][k] -= gauss[i][k] * gauss[j][i] / gauss[i][i];
          gauss[j][i] = 0;
        }
      }
    }
  }
  pt[n - 1] = 1 / gauss[n - 1][n - 1];
  for(i = n - 2; i > 0; i--){
    if(grad[i] != 0){
      for(j = n - 1; j > i; j--){
        if(grad[j] != 0){
          pt[i] -= pt[j] * gauss[i][j];
        }
      }
      pt[i] /= gauss[i][i];
    }
  }
  //maximize_flow
  double min = INF, cm;
  for(i = 0; i < dr; i += 2){
    if(grad[nd[i]] != 0 && grad[nd[i + 1]] != 0){
      if(cmp(pt[nd[i]], pt[nd[i + 1]]) != 0){
        cm = cpc[i] / myabs(pt[nd[i]] - pt[nd[i + 1]]);
        if(cm < min)
          min = cm;
      }
    }
  }
  FILE *out = fopen("flux.out", "w");
  if(dfs(0) != n - 1)
    fprintf(out, "0.000");
  else
    fprintf(out, "%.3lf", min);
  fclose(out);
  return 0;
}