Pagini recente » Cod sursa (job #911645) | Cod sursa (job #1594096) | Cod sursa (job #2174141) | Cod sursa (job #1901560) | Cod sursa (job #1966039)
#include <fstream>
#include <iomanip>
#include <algorithm>
using namespace std;
const int NMAX = 100 + 5;
const double EPS = 1E-8;
int N;
double mat[NMAX][NMAX];
void _swap(int lin1, int lin2, int start) {
for (int i = start; i <= N + 1; ++ i)
swap(mat[lin1][i], mat[lin2][i]);
}
void mult(int lin, double val, int start) {
for (int i = start; i <= N + 1; ++ i)
mat[lin][i] *= val;
}
void subtr(int lin1, double alpha, int lin2, int start) {
for (int i = start; i <= N + 1; ++ i)
mat[lin1][i] -= alpha * mat[lin2][i];
}
double potentials[NMAX];
void Gauss() {
for (int col = 1; col <= N; ++ col) {
int who = 0;
for (int i = col; i <= N; ++ i)
if (fabs(mat[i][col]) >= EPS) {
who = i;
break;
}
_swap(col, who, col);
mult(col, 1 / mat[col][col], col);
for (int i = col + 1; i <= N; ++ i)
if (fabs(mat[i][col]) >= EPS)
subtr(i, mat[i][col], col, col);
}
for (int i = N; i; -- i) {
potentials[i] = mat[i][N + 1];
for (int j = i + 1; j <= N; ++ j)
potentials[i] -= potentials[j] * mat[i][j];
}
}
const int MMAX = 5000 + 5;
struct Edge {
int a, b, c;
} edges[MMAX];
vector <int> graph[NMAX];
int label[NMAX];
int labels;
void dfs(int node) {
label[node] = ++ labels;
for (auto it: graph[node])
if (!label[it])
dfs(it);
}
vector <int> newGraph[NMAX];
int main()
{
ifstream cin("flux.in");
ofstream cout("flux.out");
int M = 0;
cin >> N >> M;
for (int i = 1; i <= M; ++ i) {
cin >> edges[i].a >> edges[i].b >> edges[i].c;
graph[edges[i].a].push_back(edges[i].b);
graph[edges[i].b].push_back(edges[i].a);
}
//Relabel
dfs(1);
int T = label[N];
for (int i = 1; i <= M; ++ i) {
edges[i].a = label[edges[i].a];
edges[i].b = label[edges[i].b];
newGraph[edges[i].a].push_back(edges[i].b);
newGraph[edges[i].b].push_back(edges[i].a);
}
N = labels;
//Find potentials
potentials[1] = 0;
mat[1][1] = 1;
mat[1][N + 1] = 0;
potentials[T] = 1;
mat[T][T] = 1;
mat[T][N + 1] = 1;
for (int i = 2; i <= N; ++ i)
if (i != T) {
mat[i][i] = newGraph[i].size();
for (auto it: newGraph[i])
-- mat[i][it];
}
Gauss();
//Compute MaxFlow
double atMost = 1E9;
for (int i = 1; i <= M; ++ i)
if (edges[i].a)
atMost = min(atMost, edges[i].c / fabs(potentials[edges[i].a] - potentials[edges[i].b]));
double flow = 0;
for (auto it: newGraph[1])
flow += atMost * potentials[it];
cout << fixed << setprecision(6) << flow << '\n';
return 0;
}