Question link: http://acm.hdu.edu.cn/showproblem.php? PID = 1, 5988
Question:
Given N points and M directed edges, each point is a place to eat and each person has a box of meals. There are s people at each point, and there are B lunch boxes. Each side can only be walked C times, and each side has a wire,
When the first person passes, the wire will not be damaged. From the second person, each time there is a probability that P will destroy the wire. So that everyone can eat and find the minimum probability of breaking the wire.
Solution:
The question requires us to find the minimum probability of damage to the wire, that is, a minimum product problem. With log, we can change it to addition, so we can use Liu to solve the problem.
Create a graph as follows:
① The Source point st creates an edge to the I-th user, and the traffic is S.
② When I personally build an edge to the sink, the traffic is B.
③ U-> V edge, the traffic is C, and the cost is-log (1-p ).
Then run the fee stream. 1-exp (-cost) is the answer.
Code
1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <cmath> 5 # include <algorithm> 6 # include <queue> 7 # include <vector> 8 # define ll long 9 # define PII pair <double, int> 10 # define PLL pair <long, long> 11 # define rep (I, a, B) for (INT I = A; I <= B; I ++) 12 # define per (I, a, B) for (INT I = A; I> = B; I --) 13 # define fast_io IOs :: sync_with_stdio (false); cin. tie (0); 14 # define bug cout <" Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "<Endl; 15 # define bugc (_) cout <(# _) <" = "<(_) <Endl; 16 using namespace STD; 17 const double EPS = 1e-8; 18 const int n = 1E2 + 5; 19 const int M = 1e5 + 5; 20 const int INF = 0x3f3f3f; 21 22 struct node {23 int to, next, flow; 24 Double cost; 25} edge [M * 2]; 26 27 int CNT, St, en, n, m; 28 int head [N], pre [N]; 29 double dis [N]; // dis [I] indicates the maximum probability of no damage to the wire until dis [I] 30 bool vis [N]; 31 32 int SGN (Double X) {return x <-EPS? -1: x> EPS;} 33 34 void Init () {35 CNT = 2; 36 memset (Head, 0, sizeof (head )); 37} 38 39 void Link (int u, int V, int flow, double cost) {40 edge [CNT] = node {v, head [u], flow, cost }; 41 head [u] = CNT ++; 42 edge [CNT] = node {u, head [v], 0,-cost }; 43 head [v] = CNT ++; 44} 45 46 bool spfa () {47 memset (PRE, 0, sizeof (pre); 48 memset (VIS, false, sizeof (VIS); 49 for (INT I = sT; I <= en; I ++) dis [I] = inf; 50 dis [st] = 0; 51 queue <int> Q; 52 Q. Push (ST); 53 While (! Q. empty () {54 int u = Q. front (); 55 Q. pop (); 56 vis [u] = false; 57 for (INT I = head [u]; I; I = edge [I]. next) {58 node T = edge [I]; 59 If (T. flow & dis [T. to]> dis [u] + T. cost + EPS) {60 dis [T. to] = dis [u] + T. cost; 61 Pre [T. to] = I; 62 if (! Vis [T. to]) {63 vis [T. to] = true; 64 Q. push (T. to); 65} 66} 67} 68} 69 If (DIS [En] = inf) 70 return false; 71 return true; 72} 73 74 void mcmf (Int & flow, double & cost) {75 while (spfa () {76 int mmin = inf; 77 for (INT I = pre [En]; I; I = pre [edge [I ^ 1]. to]) {78 mmin = min (mmin, edge [I]. flow); 79} 80 for (INT I = pre [En]; I; I = pre [edge [I ^ 1]. to]) {81 edge [I]. flow-= mmin; 82 edge [I ^ 1]. flow + = mmin; 83 cost + = edge [I]. cost * mmin; 84} 85 flow + = mmin; 86} 87} 88 89 int main () {90 int t; 91 scanf ("% d", & T ); 92 While (t --) {93 Init (); 94 int n, m; 95 scanf ("% d", & N, & M); 96 ST = 0, en = n + 1; 97 for (INT I = 1; I <= N; I ++) {98 int S, B; 99 scanf ("% d ", & S, & B); 100 if (S-B> 0) Link (St, I, S-B, 0); 101 if (S-B <0) link (I, en, B-S, 0); 102} 103 for (INT I = 1; I <= m; I ++) {104 int U, V, flow; 105 Double P; 106 scanf ("% d % lf", & U, & V, & flow, & P ); 107 P =-log (1-p); 108 If (flow> 0) Link (u, v, 109); If (flow> 1) Link (u, v, flow-1, P); 110} 111 int flow = 0; 112 double cost = 0; 113 mcmf (flow, cost); 114 cost = exp (-cost ); 115 printf ("%. 2f \ n ", 1-cost); 116} 117 return 0; 118}
HDU 5988 coding Contest (cost stream + floating point number)