Problem Description
A coding contest will be held in this university, in a huge playground. The whole playground would be divided into N blocks, and there would be M directed paths linking these blocks. The i-th path goes from the u_i-th block to the v_i-th block. Your task is to solve the lunch issue. According to the arrangement, there are s_i competitors in the i-th block. Limited to the size of table, b_i bags of lunch including breads, sausages and milk would be put in the i-th block. As a result, some competitors need to move to another block to access lunch. However, the playground is temporary, as a result there would be so many wires on the path.
For the i-th path, the wires have been stabilized at first and the first competitor who walker through it would not break the wires. Since then, however, when a person go through the i - th path, there is a chance of p_i to touch
the wires and affect the whole networks. Moreover, to protect these wires, no more than c_i competitors are allowed to walk through the i-th path.
Now you need to find a way for all competitors to get their lunch, and minimize the possibility of network crashing.ios
Input
The first line of input contains an integer t which is the number of test cases. Then t test cases follow.
For each test case, the first line consists of two integers N (N ≤ 100) and M (M ≤ 5000). Each of the next N lines contains two integers si and b_i (s_i , b_i ≤ 200).
Each of the next M lines contains three integers u_i , v_i and c_i(c_i ≤ 100) and a float-point number p_i(0 < p_i < 1).
It is guaranteed that there is at least one way to let every competitor has lunch.c++
Output
For each turn of each case, output the minimum possibility that the networks would break down. Round it to 2 digits.git
#include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #define TS printf("!!!\n") #define pb push_back #define inf 1e9 //std::ios::sync_with_stdio(false); using namespace std; //priority_queue<int,vector<int>,greater<int>> que; const double EPS = 1.0e-8; const double eps = 1.0e-8; typedef pair<int, int> pairint; typedef long long ll; typedef unsigned long long ull; const int maxn = 205; const int maxm = 300; //next_permutation int level[205]; int Si, Ei, Ci; struct Edge { int from, to, cap, flow; double cost; Edge() {} Edge(int f, int t, int c, int fl, double co): from(f), to(t), cap(c), flow(fl), cost(co) {} }; struct MCMF { int n, m, s, t; vector<Edge>edges; vector<int>g[maxn]; bool inq[maxn]; double d[maxn]; int p[maxn]; int a[maxn]; void init(int n, int s, int t) { this->n = n; this->s = s; this->t = t; edges.clear(); for (int i = 0; i <= n; i++) { g[i].clear(); } } void AddEdge(int from, int to, int cap, double cost) { edges.push_back(Edge(from, to, cap, 0, cost)); edges.push_back(Edge(to, from, 0, 0, -cost)); m = edges.size(); g[from].push_back(m - 2); g[to].push_back(m - 1); } bool BellmanFord(int &flow, double &cost) { for (int i = 0; i <= n; i++) { d[i] = inf; } memset(inq, 0, sizeof(inq)); d[s] = 0, a[s] = inf, inq[s] = 1, p[s] = 0; queue<int>q; q.push(s); while (!q.empty()) { int u = q.front(); q.pop(); inq[u] = 0; for (int i = 0; i < g[u].size(); i++) { Edge &e = edges[g[u][i]]; if (e.cap > e.flow && d[e.to] > d[u] + e.cost + eps) { d[e.to] = d[u] + e.cost; p[e.to] = g[u][i]; a[e.to] = min(a[u], e.cap - e.flow); if (!inq[e.to]) { q.push(e.to); inq[e.to] = 1; } } } } if (d[t] == inf) { return false; } flow += a[t]; cost += a[t] * d[t]; int u = t; while (u != s) { edges[p[u]].flow += a[t]; edges[p[u] ^ 1].flow -= a[t]; u = edges[p[u]].from; } return true; } double Min_cost(int &flow, double &cost) { flow = 0, cost = 0; while (BellmanFord(flow, cost)); return cost; } } mc; int main() { int time; scanf("%d", &time); while (time--) { int n, m; int a, b; cin >> n >> m; int s = 0; int t = 2 * n + 1; mc.init(n * 2 + 1, s, t); for (int i = 1; i <= n; i++) { scanf("%d %d", &a, &b); //cin >> a >> b; if (a == b) { continue; } else { if (a > b) { mc.AddEdge(s, i, a - b, 0); } else { mc.AddEdge(i, t, b - a, 0); } } } int u, v, c; double p; for (int i = 1; i <= m; i++) { scanf("%d %d %d %lf", &u, &v, &c, &p); //cin >> u >> v >> c >> p; p = -log(1 - p); if (c == 0) { continue; } else if (c == 1) { mc.AddEdge(u, v, 1, 0); } else { mc.AddEdge(u, v, 1, 0); mc.AddEdge(u, v, c - 1, p); } } int flow = 0; double cost = 0; cost = mc.Min_cost(flow, cost); cost = exp(-cost); printf("%.2f\n", 1 - cost); } }