Problem description:
X set (Number 1 ~ M), y set (number m + 1 ~ N ). N, m <100. Given several combinations (x, y) (equivalent to ing X-> Y), you can have several combinations (Allocation) at the same time ).
Analysis:
The topic may not be well described. This is obviously a problem of maximum matching of bipartite graphs. (Bipartite Graph)
It can be solved using the Hungary algorithm or network stream. This section describes the Hungarian algorithm.
At the core of the Hungarian algorithm is to find the augmented path. Constantly search for the augmented path and update the existing matching M (M can be regarded as a special ing of X-> Y). Each update can increase the number of matching requests by one. If the augmented path cannot be found, M is the largest matching.
Specific algorithm process:
① Mark X as U, and y AS v. Note that f [v] is the U corresponding to the U-> V ing, that is, the V ing point, F [v] = u. (Initial resetting) vis [u] records whether the dot U has accessed the augmented path for this search.
DFS (u) indicates whether there is an extended path starting from Point U. If 1 is returned, otherwise 0 is returned.
② Traverse the X set, (u = 1 ~ M), each traversal of vis [] is cleared, and DFS (U). If an augmented path (that is, DFS (u) = 1) is found, the matching number is added to 1. The final number of matches is the maximum.
③ In DFS, find V from U (adjacent table save graph ),
I. If V has not been accessed this time (!!), That is, vis [v] = 0.
1) if V is a non-built vertex, that is, F [v] = 0 (no corresponding vertex exists) (indicating that the augmented path is found, ending with V ).
2) If DFS (F [v]) = 1, that is, F [v] =0, V is the cap point, f [v] is the U' corresponding to the current matching m of V (the definition of The Link augmented path, which is staggered by the actual situation ). DFS (U') = 1, which also indicates that the augmented path is found. V is in this augmented path.
Therefore, the preceding two conditions are parallel or (|.
So M and this augmented path are reversed. F [v] = U (updated m), return 1; (locate, backtrack ).
3) No. traverse the next adjacent point V of the U.
II. If Vis! = 0; not processed.
In fact, I still don't quite understand this algorithm.
Code:
# Include <cstdio> <br/> # include <cstring> <br/> # include <vector> <br/> using namespace STD; </P> <p> inline int RINT () {int X; scanf ("% d", & X); Return X ;} <br/> # define maxn 110 <br/> vector <int> G [maxn]; <br/> int vis [maxn]; <br/> int flag [maxn]; // 0-uncovered/corresponding point-covered <br/> int n, m; <br/> int DFS (int u) <br/> {<br/> for (INT I = 0; I <(INT) g [u]. size (); I ++) <br/>{< br/> int v = G [u] [I]; <br/> If (! Vis [v]) // inaccessible <br/>{< br/> vis [v] = 1; <br/> If (! Flag [v] | DFS (flag [v]) //! Not the DFS (V)-> DFS (flag [v]) ing point <br/>{< br/> flag [v] = u; <br/> return 1; <br/>}< br/> return 0; <br/>}< br/> int Hungary () <br/>{< br/> memset (flag, 0, sizeof (FLAG); <br/> int ans = 0; <br/> // For (INT I = 1; I <= N; I ++) // n ?? Each vertex <br/> for (INT I = 1; I <= m; I ++) // sets the X point 1 ~ M <br/> {<br/> memset (VIS, 0, sizeof (VIS); <br/> If (DFS (I) ans ++; <br/>}< br/> return ans; <br/>}< br/> void read_graph () <br/>{< br/> while (1) <br/>{< br/> int u = RINT (), V = RINT (); <br/> If (u =-1) break; <br/> G [u]. push_back (V); // the process of searching is always starting from the X set. U, flag [v] ing back to u '... <br/> // G [v]. push_back (U); <br/>}< br/> void print_ans () // output matching m <br/>{< br/> for (INT I = m + 1; I <= N; I ++) // flag [v] = u... V = m + 1 ~ N <br/> If (flag [I]) // V is the cap point, output matched edge <br/>{< br/> printf ("% d-> % d/N", flag [I], I ); <br/>}< br/> int main () <br/>{< br/> M = RINT (); <br/> N = RINT (); <br/> read_graph (); <br/> printf ("% d/N", Hungary ()); <br/> print_ans (); <br/>}