I. INTRODUCTION
Binary graph matching algorithm is a very useful algorithm, we first introduced from a simple topic.
Give you n a fruit, m box, each fruit can only be placed in a few boxes, each box can only put a fruit, ask how to arrange to put in the box of fruit most.
How to write? Violence, can try. But whether it is violence or what algorithm, all need to face a situation-the fruit behind if no box put, can not ignore, should make room. Yes, Teng .
The most important idea of the binary graph algorithm is to free
Two. Algorithmic flow
There are two main algorithms for binary graph, one is Hungarian algorithm and one is km algorithm.
Let's first explain the Hungarian algorithm (KM algorithm see directory 5th)
To make it easier to understand, let's draw a picture first.
\ (x_{1}\)~\ (x_{4}\)It refers to the fruit,\ (y_{1}\)~\ (y_{4}\)Refers to the box, each fruit has its own preference.
At this time, the Hungarian algorithm took you to find\ (x_{1}\)Fruit, you find\ (y_{1}\)It's an empty box, so you put\ (x_{1}\)Into\ (y_{1}\)(even a red line)
Then, the Hungarian algorithm took you to find the\ (x_{2}\), you find\ (y_{2}\)It's an empty box, so you put\ (x_{2}\)Put in\ (y_{2}\)(even a red line)
You go back and find it.\ (x_{3}\), but you find\ (y_{1}\)、\ (y_{2}\)Have already put things, how to help, so let go of the matter?
No, the Hungarian algorithm tells you that you need to do some experimenting. So you try to\ (x_{3}\)Into\ (y_{2}\), and ready to give\ (x_{2}\)Find a box again, but you find\ (y_{1}\)There are also fruits ... So you do it again, so you're going to give\ (x_{1}\)Find a box again, it happened,\ (y_{3}\)is empty, so you will\ (x_{1}\)Put in\ (y_{3}\)
So we are constantly looking for the process, experienced a\ (x_{?} \)-\ (y_{?} \)--->\ (x_{?} \)---, ... Path, which we call the augmented road
(Middle, yellow edge is temporarily disassembled side, indicating trying)
So happy, everyone has their own destination.
And then we found it.\ (x_{4}\), but no matter howTengThere is no way, only to\ (x_{4}\)Let's go outside and blow the northwest.
So the most important point of the binary graph algorithm is to Teng , to make great efforts to Teng
Three. Code (Hungarian algorithm)
Zju1140 Courses Course
Description
Give the total number of courses P (1<=p<100), the total number of students N (1<=N<=300)
Each student may have chosen a course, there may be many doors, or there may not be.
Asked to elect P students to form an association, each student representing a course,
And each course has a student to represent it.
Input
First, the number of test data.
and the P,n.
The following P-lines represent the electives of the students from the first course to the P-gate course. First give the number of people to take the elective,
And the number of these people.
Output
Can you form an association like this?
Sample Input
2
3 3
3 1 2 3
2 1 2
1 1
3 3
2 1 3
2 1 3
1 1
Sample Output
YES
NO
Bare binary Graph Max match, direct on code
/*program from wolfycz*/#include <cmath> #include <cstdio> #include <cstring> #include <iostream > #include <algorithm> #define INF 0x7f7f7f7fusing namespace std;typedef long long ll;typedef unsigned int UI; typedef unsigned long long ull;inline int read () {int X=0,f=1;char ch=getchar (); for (;ch< ' 0 ' | | Ch> ' 9 '; Ch=getchar ()) if (ch== '-') f=-1; for (; ch>= ' 0 ' &&ch<= ' 9 '; Ch=getchar ()) x= (x<<1) + (x<<3) +ch-' 0 '; return x*f;} inline void print (int x) {if (x>=10) print (X/10); Putchar (x%10+ ' 0 ');} const int N=1e2,m=3e2;int path[m+10],pre[n*m+10],now[n*m+10],child[n*m+10];int Tot,n,m;bool use[M+10];void join (int x , int y) {pre[++tot]=now[x],now[x]=tot,child[tot]=y;} BOOL Check (int x) {for (int p=now[x],son=child[p];p; p=pre[p],son=child[p]) {if (Use[son]) continue; Use[son]=1; if (path[son]<0| | Check (Path[son])) {Path[son]=x;return 1;} } return 0;} void work () {int res=0; for (int i=1;i<=n;i++) {memset (use,0,sizeof (use)); if (check (i)) res++; } printf (res==n? ") Yes\n ":" no\n ");} void Init () {tot=0; memset (Now,0,sizeof (now)); memset (path,255,sizeof (path));} int main () {for (int data=read ();D ata;data--) {init (); N=read (), M=read (); for (int i=1;i<=n;i++) for (int x=read (), j;x;x--) J=read (), join (I,J); Work (); } return 0;}
Four. Some proofs about the binary chart
(There are many ways to match the ring, not discussed here)
Set maximum number of matches to \ (k\) , in points of \ (n\)
minimum point cover set : is to use the fewest set of points \ (g\), so that the left or right end of all segments on this graph belong to \ (g\)
Prove:
Since all the most matched segments do not intersect, just take the left or right end points, so that each segment of the maximum match corresponds to a point, with a total of \ (k\)
Because it is the maximum match, there is no augmented path, and when the endpoints of the two segments intersect, you know that it must not be the maximum match.
Maximum Point independent set : in a graph \ (m\) , take the most points, so that each point is not adjacent
Prove:
When a line segment \ (ab\) belongs to an edge in the maximum match, it must have an endpoint that has no other edges, so the maximum matching segment has a total of \ (k\) on it,
There are \ (n-2*k\) on segments that do not belong to the maximum match (each of the maximum matching segments corresponds to two points)
Because we take the endpoint without the other side, naturally there is no point on the line that is not the largest match and its adjacent
So there are a total of \ (n-2*k+k=n-k\) points
Minimum Edge Overlay : Take the fewest set of edges \ (g\)so that all vertices are in \ (g\)
Prove:
In fact, the maximum point independent set is similar, just point can also be regarded as the edge, the largest match in the edge of the 2*k\ (the) point,
The remaining \ (n-2*k\) points are to be covered with \ (n-2*k\) line segments, so there is a total of \ (n-2*k+k=n-k\)
Minimum Path overlay : In a single graph, the entire graph is covered with disjoint paths
Prove:
Because each point is initially a path, there are a total of n disjoint paths. Each time we add a side in the binary map is equivalent to the two path is synthesized a path, because the path can not have a common point, so the addition of the edges can not have a common point, and the maximum number of k\ (the) , so the answer is \ (n-k\)
Five. KM algorithm
Although the Hungarian algorithm is good, there are certain limitations, if the title is not the maximum match but the maximum weight matching, the Hungarian algorithm seems powerless, so we need to use a new algorithm, KM algorithm
The general description of the KM algorithm can basically be summed up in the following several steps:
(1) Initialization of feasible benchmarks
(2) Searching for complete match with Hungarian algorithm
(3) Modify the feasible benchmark if no complete match is found
(4) Repeat (2) (3) until a complete match is found for the equal sub-graph
Complete match: If one match, each vertex in the diagram is associated with an edge in the graph, it is said to be an exact match, also known as a complete match.
Theorem: Set \ (m\) is a complete match of a weighted complete binary graph \ (g\) , which gives each vertex a workable top mark ( i\) ( x\) vertex ( lx[i) \) indicates that the j\ \ ( y\) Vertex is a viable standard ( ly[j]\) , if all sides (I,J) in G, there \ (lx[i]+ly[j]>=w I [J]\] is established (\ (w[i][j]\) means the right of the edge), and for all edges (i,j) in M, there is a \ (lx[i]+ly[j]=w[i][j]\) , then M is an optimal match of Figure G.
So what are the possible benchmarks? To facilitate understanding, we explain by an example, and some analogy
We assume \ (x_{? }\) for some guests,\ (y_{?} \) for some goods, the guests have certain expectations of the goods, you need to let the guests buy some goods, so that their expectations are greatest (regardless of economic problems)
Then these guests in the distribution of goods will inevitably have some disputes, so we can find an augmented road, augmented Road must have an odd number of nodes, and must be a guest point more out of one. Therefore, we need to make a slight adjustment to the customer and the benchmark of the goods, yes, the binary chart can add some new points to meet the customers ' needs and resolve their disputes.
We set \ (lx\) as the customer's benchmark,\ (ly\) for the product benchmark.
The customer's benchmark must be their expectations, so the benchmark of the commodity, it must be their expected increase in value
Therefore, the initial value of\ (lx\) is the maximum expectation of a customer for all goods, and the initial value of\ (ly\) is zero.
When the current benchmark does not find a complete match, we are going to allow more customers to buy other unselected items, so \ ( d=min\){\ (lx[i]+ly[j]-w[i][j]\)} (\ (i\) For the augmented road customer point,\ (j\) is not on the augmented road of the goods point) i,j the location is very good understanding, there must be a quarrel with the guests to find the goods without dispute
Then \ (d\) is the value I want to lower, so I give all the guests on the augmented road to the maximum expectations of the total reduction of (d\), but we can not lose more, each time the whole can only reduce the (d\), So we have to add all the products on the road to the expectation of d\, so as to ensure the overall stability, and can add new products to meet customer needs.
(not good, readers still look at the code bar)
Six. code (KM algorithm)
Description
You were just hired as CEO of the local junkyard. One of your jobs is dealing with the incoming trash and sorting it for recycling. The trash comes every day in n containers and each of the these containers contains certain amount of each of the N types of T Rash. Given The amount of trash in the containers find the optimal a-to sort the trash. Sorting the trash means putting every type of trash in separate container. Each of the given containers have infinite capacity. The effort for moving one unit of trash from container I to J is 1 if I! = J otherwise it is 0.You be to minimize the tot Al effort.
you are employed by the local waste disposal company as CEO, and one of your tasks is to dispose of the imported rubbish and classify the rubbish for recycling. Every day, the rubbish will have several containers to come, each container contains several kinds of rubbish. The number of rubbish in a given container, please find the best way to classify the rubbish. Sorting rubbish separates each type of rubbish into different containers. The capacity of each container is unlimited. Moving a unit of garbage costs a lot, from the container I to J is 1 (i<>j, otherwise the cost is 0), you have to minimize the cost.
Input
The first line contains the number n (1 <= n <=), the rest of the input file contains the descriptions of the CO Ntainers. The 1 + i-th line contains the desctiption of the i-th container the j-th amount (0 <= amount <= Enotes The amount of the j-th type of trash in the i-th container.
The first behavior n (1 <= n <= 150), the following is the case of the container. The number of J types of garbage in the first container of I+1 Act amount (0 <= amount <= 100).
Output
You should write the minimal effort which is required for sorting the trash.
The minimum price required to classify these wastes.
Sample Input
4
62 41 86 94
73 58 11 12
69 93 89 88
81 40 69 13
Sample Output
650
/*program from wolfycz*/#include <cmath> #include <cstdio> #include <cstring> #include <iostream > #include <algorithm> #define INF 0x7f7f7f7fusing namespace std;typedef long long ll;typedef unsigned int UI; typedef unsigned long long ull;inline int read () {int X=0,f=1;char ch=getchar (); for (;ch< ' 0 ' | | Ch> ' 9 '; Ch=getchar ()) if (ch== '-') f=-1; for (; ch>= ' 0 ' &&ch<= ' 9 '; Ch=getchar ()) x= (x<<1) + (x<<3) +ch-' 0 '; return x*f;} inline void print (int x) {if (x>=10) print (X/10); Putchar (x%10+ ' 0 ');} const int N=1.5e2;int path[n+10],lx[n+10],ly[n+10];int Map[n+10][n+10];bool visx[n+10],visy[n+10];int n,ans;bool Check (int x) {visx[x]=1; for (int y=1;y<=n;y++) {if (!visy[y]&&lx[x]+ly[y]==map[x][y]) {visy[y]=1; if (path[y]<0| | Check (Path[y])) {path[y]=x; return 1; }}} return 0;} int Km () {int sum=0; memset (Path,-1,sizeof (path)); for (int i=1;i<=n;i++) {while (1) {memset (visx,0,sizeof (VISX)); memset (visy,0,sizeof (Visy)); if (check (i)) break; int d=inf; for (int i=1;i<=n;i++) if (Visx[i]) for (int j=1;j<=n;j++) if (!visy[j]) D=mi N (D,lx[i]+ly[j]-map[i][j]); for (int i=1;i<=n;i++) if (visx[i]) Lx[i]-=d; for (int i=1;i<=n;i++) if (visy[i]) Ly[i]+=d; }} for (int i=1;i<=n;i++) if (path[i]!=-1) sum+=map[path[i]][i]; return sum;} int main () {n=read (); for (int i=1;i<=n;i++) {lx[i]=-inf; for (int j=1;j<=n;j++) Ans+=map[i][j]=read (), Lx[i]=max (Lx[i],map[i][j]); } printf ("%d\n", ans-km ()); return 0;}
Algorithm template--two graph matching