51nod 2006 Pilot Pairing (Bipartite Maximum Matching)



      51th 2006

During World War II, the Royal Air Force recruited a large number of foreign pilots from occupied countries. Every aircraft sent by the RAF requires two pilots, one British and one foreign pilot, who are compatible in both navigational skills and language. Among the many pilots, each foreign pilot works well with several other British pilots. How to choose pilots to fly in pairs so that you can send the most planes at once. For a given foreign pilot fit with British pilots, program to find an optimal pilot pairing that will allow the RAF to field the most aircraft at a time. 


Input
Line 1 has 2 positive integers m and n. n is the total number of RAF pilots (n<100); m is the number of foreign pilots. Foreign pilots are numbered 1~m; British pilots are numbered m+1~n. The next line has 2 positive integers i and j, indicating that foreign pilot i can cooperate with British pilot j. The input ends with 2 -1s at the end.
Output
Row 1 is the maximum number of aircraft M that the best pilot pairing scheme can send at one time. If the desired optimal pilot pairing solution does not exist, output 'No Solution!'.
Input example
5 10
1 7
1 8
2 6
2 9
2 10
3 7
3 8
4 7
4 8
5 10
-1 -1
Output example
4

analyze:

It is obviously the most naked problem - the maximum matching number of bipartite graphs. using the Hungarian algorithm. .

The figure is a bipartite graph.

Each u can be matched with multiple v,

The so-called maximum matching of the bipartite graph is to find the maximum matching number on the premise that each u can only be matched with one v.

Hungarian algorithm:

Originally an undirected graph, it can be regarded as directed, from u to v.

Using recursion, it is the first time to do a bipartite graph problem, and the code is explained in detail. .

#include <iostream>
#include <cstring>
#include <vector>

using namespace std;

vector<int> pic[110]; //vector stores the original bipartite graph.

bool vis[110]; //Initialize before each search, record whether each m has been searched in this search.
int match[110]; //Save matching information, no match is -1.

bool find_m(int n) //returns whether m matching n can be found (that is, n is the element on the left, m is the element on the right)
{
    for(int i = 0;i < pic[n].size();i ++)
    {
        int m = pic[n][i]; //The current m is one of the m that n can match.
        if(!vis[m]) //If this m has not been visited
        {
            vis[m] = true;
            if(match[m] == -1 || find_m(match[m])) //If the m does not match, or the current n that matches the m can also match other m
            {
                match[m] = n;         
                return true; //match successful
            }
        }
    }
    return false; //match failed
}

intmain()
{
    int m,n;
    int a,b;
    int sum = 0;
    cin>>m>>n;
    while(cin>>a>>b && (a != -1 || b != -1))  //先存图
    {
        pic[a].push_back(b);
    }
    for(int i = 1;i <= n;i ++)   //初始化
        match[i] = -1;
    for(int i= 1;i <= m;i ++)
    {
        memset(vis,0,sizeof(vis)); //initialization
        if(find_m(i))
            sum++;
    }
    cout<<sum<<endl;
    return 0;
}


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326483186&siteId=291194637