In year XXXX, the earth fought with aliens, and then there was an n * m grid where aliens landed at some locations, because aliens were fierce, so they must be wiped out. Now we can put some laser guns at the beginning of some rows or columns. The characteristic of these guns is that when you put them in the first line, you will destroy the enemies in this line, and put them in the first line to eliminate the enemies in the first column. However, the placement of these guns also requires a certain amount of money. These fees have been provided, and the total cost is the sum of the costs of these guns. Currently, the minimum charge is required.
After we see the product, we can convert it to addition, that is, take the log, but do not know what the data is, will it exceed double, just give a try.
Then we can see that it is a model with the minimum vertices of a bipartite graph.
Then, the graph is created. The Source Vertex is connected to all row nodes, and the value is the log that is consumed accordingly. Then, the column node is connected to the sink vertex, and the value is the log that is consumed accordingly, the connected edge of the row and column represents the corresponding aliens, and the value is INF.
Note that INF cannot be too large because of the precision problem of double. If INF has too many digits and the maximum stream has decimal places, if there are eight digits after the decimal point, if there are too many digits before the decimal point, precision will be lost.
You can use the exp function to obtain the final result.
[Cpp]
# Include <iostream>
# Include <algorithm>
# Include <cstring>
# Include <string>
# Include <cstdio>
# Include <cmath>
# Include <queue>
# Include <map>
# Include <set>
# Define eps 1e-5
# Define maxn111
# Define MAXM 55555
# Define INF 1000007
Using namespace std;
Struct node
{
Int v;
Double c, f;
Int next, r;
} Edge [MAXM];
Int dist [MAXN], nm [MAXN], src, des, n;
Int head [MAXN], e;
Void add (int x, int y, double c)
{
Edge [e]. v = y;
Edge [e]. c = c;
Edge [e]. f = 0;
Edge [e]. r = e + 1;
Edge [e]. next = head [x];
Head [x] = e ++;
Edge [e]. v = x;
Edge [e]. c = 0;
Edge [e]. f = 0;
Edge [e]. r = e-1;
Edge [e]. next = head [y];
Head [y] = e ++;
}
Void rev_BFS ()
{
Int Q [MAXN], h = 0, t = 0;
For (int I = 1; I <= n; ++ I)
{
Dist [I] = MAXN;
Nm [I] = 0;
}
Q [t ++] = des;
Dist [des] = 0;
Nm [0] = 1;
While (h! = T)
{
Int v = Q [h ++];
For (int I = head [v]; I! =-1; I = edge [I]. next)
{
If (edge [edge [I]. r]. c = 0 | dist [edge [I]. v] <MAXN) continue;
Dist [edge [I]. v] = dist [v] + 1;
++ Nm [dist [edge [I]. v];
Q [t ++] = edge [I]. v;
}
}
}
Void init ()
{
E = 0;
Memset (head,-1, sizeof (head ));
}
Double maxflow ()
{
Rev_BFS ();
Int u;
Double total = 0;
Int cur [MAXN], rpath [MAXN];
For (int I = 1; I <= n; ++ I) cur [I] = head [I];
U = src;
While (dist [src] <n)
{
If (u = des) // find an augmenting path
{
Double tf = INF;
For (int I = src; I! = Des; I = edge [cur [I]. v)
Tf = min (tf, edge [cur [I]. c );
For (int I = src; I! = Des; I = edge [cur [I]. v)
{
Edge [cur [I]. c-= tf;
Edge [edge [cur [I]. r]. c + = tf;
Edge [cur [I]. f + = tf;
Edge [edge [cur [I]. r]. f-= tf;
}
Total + = tf;
U = src;
}
Int I;
For (I = cur [u]; I! =-1; I = edge [I]. next)
If (edge [I]. c> 0 & dist [u] = dist [edge [I]. v] + 1) break;
If (I! =-1) // find an admissible arc, then Advance
{
Cur [u] = I;
Rpath [edge [I]. v] = edge [I]. r;
U = edge [I]. v;
}
Else // no admissible arc, then relabel this vtex
{
If (0 = (-- nm [dist [u]) break; // GAP cut, Important!
Cur [u] = head [u];
Int mindist = n;
For (int j = head [u]; j! =-1; j = edge [j]. next)
If (edge [j]. c> 0) mindist = min (mindist, dist [edge [j]. v]);
Dist [u] = mindist + 1;
++ Nm [dist [u];
If (u! = Src)
U = edge [rpath [u]. v; // Backtrack
}
}
Return total;
}
Int nt, m, l;
Int main ()
{
Int T, u, v;
Scanf ("% d", & T );
While (T --)
{
Scanf ("% d", & nt, & m, & l );
Src = nt + m + 1;
Des = nt + m + 2;
N = des;
Init ();
Double tmp;
For (int I = 1; I <= nt; I ++)
{
Scanf ("% lf", & tmp );
Add (src, I, log (tmp ));
}
For (int I = nt + 1; I <= nt + m; I ++)
{
Scanf ("% lf", & tmp );
Add (I, des, log (tmp ));
} Www.2cto.com
While (l --)
{
Scanf ("% d", & u, & v );
Add (u, nt + v, INF );
}
Printf ("%. 4f \ n", exp (maxflow ()));
}
Return 0;
}
Author: sdj222555