At first, we thought that the problem could be solved by binary matching, but we had to find the maximum match with both sides, and there was no way to solve it. However, if we think that the maximum stream can solve the problem of binary matching, we can use a network stream to create a graph.
At the beginning, however, the source image-food-ox-drink-sink point was created, so that although each food and drink can only be eaten by one ox, but it cannot solve the problem that every ox can only eat one copy.
If this is the case, split the Source Vertex-food-ox-drink-sink into two vertices, And the edge weight is 1. it can be solved with an Ek algorithm that is not very efficient. The EK algorithm is easy to understand.
To:
I recently reviewed the biggest stream problem. Every time I read this part of the content, I will have a new harvest. It can be said that there is no need to write the most problematic information on the Internet. However, there are too many technical terms in most documents and it is hard for beginners to understand, at least I did not understand this part several times before I learned it. So I want to back up my personal understanding.
Figure-1
-1 shows that in this transportation network, the Source Vertex S and the sink vertex T are, respectively, and the capacity of each edge is C (u, v ). The red dotted line in the figure shows a feasible stream. As shown in-2:
P (u, v)/c (u, v) respectively indicate the actual traffic and maximum capacity of the edge.
About the maximum stream
If you are familiar with what is a network stream, you can understand the maximum stream. Is to make p (s, u) reach the maximum value for any u, V-{s. MaxFlow = p (1, 2) + p (1, 3) = 2 + 1 = 3.
Before introducing the maximum flow problem, we first introduce several concepts: residual network, augmented path, reverse arc, maximum flow theorem, and the Ford-Fulkerson Method for Finding the maximum flow.
Reverse arc of the augmented path of the residual network
Observe-4. in this state, its residual network-5 is shown:
Maybe you already know what a residual network is. For a network that has found a path from S to T, just put C (u, v) the value is updated to C (u, v)-P (u, v), and the reverse arc C (v, u) is added ). The corresponding augmented Path is a simple Path from S to T on the residual network. In Figure 4, 1, 2, 4, and 7 are an augmented path, of course, 3, 4, and 7.
In addition, prior to any operation, the original directed graph is also a residual network, and it is only not updated.
Max stream Theorem
If no augmented path is found on the residual network, the current stream is the largest stream; otherwise, if the current stream is not the largest stream, there must be an augmented path.
Ford-Fulkerson Method
After introducing the above concepts, you can use the Ford-Fulkerson method to find the maximum stream. The reason is that the Ford-Fulkerson method is not an algorithm, because it can be implemented in multiple ways, and the method is not unique. The following describes an algorithm for calculating the augmented path P Based on the BFS: Edmonds-Karp.
The algorithm flow is as follows:
Set queue Q: stores the nodes that are not currently accessed. After the first node leaves the queue, it becomes the checked punctuation;
Path array: stores the augmented Path of the currently accessed nodes;
Flow Array: stores the improved Flow after a BFS traversal;
Repeat:
Path clearing;
The Source Vertex S enters Path and Q, Path [S] = 0, Flow [S] = + ∞;
While Q is not empty and vertex T is not accessed do
Begin
The first vertex of the team is u-aligned;
For each arc (u, v) do starting from u
If v does not access and arc (u, v) traffic can be improved;
Then Flow [v] = min (Flow [u], c [u] [v]) and v join and Path [v] = u;
End while
If (vertex T accessed)
Then constructs a residual network from the collection point T along the Path;
Until settlement point T not accessed
Code:
[Cpp]
# Include <stdio. h>
# Include <stdlib. h>
# Include <string. h>
# Include <math. h>
# Define inf 1000
# Define nMax 410
# Define Max (a, B) (a> B? A: B)
# Define Min (a, B) (a <B? A: B)
Int map [nMax] [nMax];
Int N, F, D;
Int path [nMax];
Int queue [nMax * 100];
Int head, end;
// Bool flag [nMax];
// Search for an augmented path
Int bfs ()
{
Int minFlow = inf, u;
Memset (path,-1, sizeof (path ));
Head = 0;
End = 1;
Queue [head] = 0;
While (head <end)
{
U = queue [head ++];
If (u = 2 * N + F + D + 1)
{
Break;
}
For (int I = 1; I <= 2 * N + F + D + 1; ++ I)
{
If (path [I] =-1 & map [u] [I])
{
If (minFlow> map [u] [I])
{
MinFlow = map [u] [I];
}
Queue [end ++] = I;
Path [I] = u;
}
}
}
If (path [2 * N + F + D + 1] =-1)
{
Return-1;
}
Return minFlow;
}
// EK algorithm. A augmented path is obtained for each wide search, and the residual network is updated.
Void Edmods_Karp ()
{
Int flow, maxFlow = 0, now, pre;
While (flow = bfs ())! =-1)
{
MaxFlow + = flow;
Now = 2 * N + F + D + 1;
While (now! = 0)
{
Pre = path [now];
Map [pre] [now]-= flow;
Map [now] [pre] + = flow;
Now = pre;
}
}
Printf ("% d \ n", maxFlow );
}
// Create a chart based on the sequence of source point-food-ox-beverage-sink point
Void buildMap ()
{
Int fNum, dNum, fd;
While (scanf ("% d", & N, & F, & D )! = EOF)
{
Memset (map, 0, sizeof (map ));
// Memset (flag, false, sizeof (flag ));
For (int I = 1; I <= N; ++ I)
{
Scanf ("% d", & fNum, & dNum );
For (int j = 0; j <fNum; ++ j)
{
Scanf ("% d", & fd );
Map [0] [fd] = 1;
Map [fd] [I + F] = 1;
}
Map [I + F] [I + F + N] = 1;
For (int j = 0; j <dNum; ++ j)
{
Scanf ("% d", & fd );
Map [fd + 2 * N + F] [F + 2 * N + D + 1] = 1;
Map [I + F + N] [fd + 2 * N + F] = 1;
}
}
Edmods_Karp ();
}
}
// Note the number given here: 0-source, 1-F indicates food, F + 1-F + N indicates the left of the ox, and F + N + 1-F + N indicates the right of the ox, F + N + 1-F + N + D is a drink beverage site. F + N + D + 1 is a collection site.
Int main ()
{
BuildMap ();
Return 0;
}