1. bipartite graph and maximum matching
What is a bipartite graph? A bipartite graph is also called a Binary Graph. It is a special model in graph theory. Set G = (V, E) to an undirected graph. If vertex V can be divided into two subsets (A, B) that are not mutually exclusive, and each edge I, j) in the graph) the two associated vertex I and j belong to these two different vertex sets (I in A, j in B) respectively. Then, graph G is called A bipartite graph.
650) this. width = 650; "src =" http://www.bkjia.com/uploads/allimg/131228/20043A422-0.jpg "alt =" 4f7c595e-020c-3f6e-b20f-55630df1781a.jpg "/>
What is matching: think of three male and four female as targets without being gay), the line represents mutual affection, but in the end only one wife and one wife, and the final matching result is a match. Matching can be empty.
What is the biggest match: On the basis of favorable feelings, we can develop up to a few pairs.
Now we need to use the Hungary algorithm to find at most several available pairs.
[Color = green] [size = medium]
The Hungary algorithm is used to find the maximum matching of binary graphs.
Ii. Maximum matching and minimum point coverage
Minimum Point Coverage: If you select a vertex, it will overwrite all the edges with it as the endpoint. You need to select the least vertex to overwrite all edges.
Minimum Cut TheoremIs a very important theorem in a bipartite graph: the maximum number of matches in a bipartite graph is equal to the minimum number of points covered in this graph.
Minimum point set overwrite = maximum match. Here, we will explain the cause. First, the minimum point set covers a certain number> = the maximum match, because if the maximum match is n, we will get n adjacent edges, it takes n points to overwrite these edges. Now let's think about why the minimum click overwrite must be <= the maximum match. The minimum click overwrite of any type of n points can be converted into a maximum match of n. Because each vertex in the least point set overwrites at least one edge with only one endpoint in the vertex set. If not, it indicates that the other endpoint of all the edges of the vertex is overwritten, therefore, this point does not need to be overwritten, which is in conflict with it in the least point set coverage), as long as each endpoint selects such an edge, it must be converted into a matching scheme that matches the number of points covered by the point set. Therefore, the maximum match must be at least the number of least point set overwrites, that is, the minimum click overwrites must be <= the maximum match. In summary, the two are equal.
Iii. Hungary Algorithm
First, let's give an example.
1. No matching at the beginning
650) this. width = 650; "src =" http://www.bkjia.com/uploads/allimg/131228/2004364U7-1.jpg "alt =" d9b44964-f903-3b3d-85fb-22994a3009f9.jpg "/>
2. Select the first x point to find the first line
650) this. width = 650; "src =" http://www.bkjia.com/uploads/allimg/131228/2004364444-2.jpg "alt =" 3aa69867-6d31-1086-bc70-675ee19dfc1c.jpg "/>
3. Select the second vertex to find the second link.
650) this. width = 650; "src =" http://www.bkjia.com/uploads/allimg/131228/20043C346-3.jpg "alt =" ce8d2b7d-eff7-3232-8a49-5d4de5e75b0d.jpg "/>
4, found that the first side of x3 x3y1 has been occupied by people, find out the x1y1 starting from the staggered path x3-y1-x1-y4, the cross path has been in the matching side x1y1 removed from the matching, add the remaining side x3y1 x1y4 to the matching
650) this. width = 650; "src =" http://www.bkjia.com/uploads/allimg/131228/20043A334-4.jpg "alt =" 3e61fee1-03fa-3daf-93ee-03cb9b4aca1d.jpg "/>
5. Similarly, add x4 and x5.
The Hungarian algorithm can have a limited depth or a higher breadth. In the preceding example, the depth is preferred. That is, if x3 matches y1 and y1, it returns a staggered path. If the breadth is preferred, it should be: x3 to find y1, y1 to match, x3 to find y2.
Deep priority Hungary algorithm code:
# Define maxn 10 // indicates the maximum number of vertices in the x and y sets! Int nx, ny; // The number of vertices in the x and y sets. int edge [maxn] [maxn]; // If edge [I] [j] is 1, ij can match int cx [maxn] And cy [maxn]. // It is used to record which yelement matches in x sets! Int visited [maxn]; // used to record whether the vertex has been accessed! Int path (int u) {int v; for (v = 0; v <ny; v ++) {if (edge [u] [v] &! Visited [v]) {visited [v] = 1; if (cy [v] =-1 | path (cy [v]) // If the v element in the y set does not match or the v element already matches, but the cy [v] can find an augmented path {cx [u] = v; cy [v] = u; return 1 ;}} return 0 ;}int maxmatch () {int res = 0; memset (cx, 0xff, sizeof (cx )); // if the initial value is-1, no matching element exists in both sets! Memset (cy, 0xff, sizeof (cy); for (int I = 0; I <= nx; I ++) {if (cx [I] =-1) {memset (visited, 0, sizeof (visitited); res + = path (I) ;}} return res ;}
4. Related POJ questions
(1)Poj3041
The question is that a bullet can take out any row or column of obstacles and ask how many bullets need to be cleared at least.
That is, to obtain the least point set overwrite.
#include<iostream>#include<stdio.h>#include<string.h>#define Max 505using namespace std;int a[Max][Max];int visit[Max];int match[Max];int N,K;int path(int u){ int v; for(v=1;v<=N;v++) { if(a[u][v] && !visit[v]) { visit[v] = 1; if(match[v] == -1 || path(match[v])) { match[v] = u; return 1; } } } return 0;}int main(){ int i,j,k,count; scanf("%d %d",&N,&K); memset(a,0,sizeof(a)); memset(match,-1,sizeof(match)); count = 0; for(i=1;i<=K;i++) { scanf("%d %d",&j,&k); a[j][k] = 1; } for(i=1;i<=N;i++) { memset(visit,0,sizeof(visit)); if(path(i)) count++; } printf("%d\n",count); return 0;}
(2) poj3020
What is important for this question is to draw a picture based on the viewpoint. You can draw an h * w-> h * w graph. vertex I has an edge with four vertices up and down to find the maximum match. The final result is the total vertices-maximum match/2.
# Include <iostream> # include <stdio. h> # include <string. h> # define Max 520 using namespace std; int a [Max] [Max]; int visit [Max]; int match [Max]; int N; char str [50] [15]; int path (int u) {int v; for (v = 1; v <= N; v ++) {if (a [u] [v] &! Visit [v]) {visit [v] = 1; if (match [v] =-1 | path (match [v]) {match [v] = u; return 1 ;}} return 0 ;}int Find () {int count = 0; int I; for (I = 1; I <= N; I ++) {memset (visit, 0, sizeof (visit); if (path (I) count ++;} return count ;} int init (int h, int w) {int ctr, I, j; int x, y; int s, d; ctr = 0; for (I = 1; I <= h; I ++) {for (j = 1; j <= w; j ++) {if (str [I] [j] = '*') {ctr ++; x = I; y = j; s = (x-1) * w + y; if (y + 1 <= w & str [x] [y + 1] = '*') {d = (x-1) * w + y + 1; a [s] [d] = 1;} if (x + 1 <= h & str [x + 1] [y] = '*') {d = (x) * w + y; a [s] [d] = 1 ;} if (Y-1> = 1 & str [x] [Y-1] = '*') {d = (x-1) * w + Y-1; a [s] [d] = 1;} if (x-1> = 1 & str [x-1] [y] = '*') {d = (X-2) * w + y; a [s] [d] = 1 ;}}} return ctr;} int main () {int I, j, k, n, totalnum, matchnum, h, w; scanf ("% d", & n); while (n --) {memset (a, 0, sizeof (a); memset (match, -1, sizeof (match); scanf ("% d", & h, & w); getchar (); for (I = 1; I <= h; I ++) {for (j = 1; j <= w; j ++) {scanf ("% c", & str [I] [j]);} getchar () ;}totalnum = init (h, w); N = h * w; matchnum = Find (); printf ("% d \ n ", totalnum-matchnum/2);} return 0;} Bipartite Graph