Today while browsing the TC forums I had a blast from the past. There was a time in which I didn't know what max flow or bipartite matching is, so I had to learn it. The process was difficult and long. While trying to understand max flow though, I did get some knowledge about solving bipartite matching without max flow. Or rather by a very simplified recursive logic that does max flow.
The good thing about the recursive logic is that it has a real life metaphor that makes it easy to remember and it is also very easy to implement. I am reposting this from an old topcoder forums post I wrote a long time ago. I thought it is good to have it in a more visible place:
Well, I have a logic for bipartite matching that makes an easy to remember and implement algorithm, not to mention it is fast:
This is as best as I could explain it:
int personInChair[m]; //personInChair[m] Points to the person that's currently on chair i bool foundChair[n]; //foundChair[i] is 1 if and only if the guy has already sit on a chair. bool canSit[n][m]; //canSit[i][j] is true if and only if person i can sit on chair j. bool alreadyTried[n]; //alreadyTried[i] is true if person i has already tried to find a new chair bool findChair(int x) // Person x will try and find a new chair... { if (alreadyTried[x]) //alreadyTried just serves the purpose of return false; //preventing infinite recursion and things like that alreadyTried[x]= true; for (int j=0; j<m; j++) if(canSit[x][j]) { int otherGuy = personInChair[j]; if ( otherGuy == -1) { //the sit is empty, just sit on it! personInChair[j] = x; foundChair[x] = true; return true; } else { //kindly ask the other guy if he can move to another chair: if ( findChair(otherGuy) ) { //he was able to move. personInChair[j] = x; foundChair[x]=true; return true; } } } return false; //No chairs available right now. } int maximumChairs() //this will return the maximum number of people // that sit on a chair. { int sum=0; fill(personInChair,personInChair+m, -1); //nobody has sit yet. fill(foundChair,foundChair+n, false); // while(true) { bool somethingChanged = false; fill(alreadyTried,alreadyTried+n, false); for (int i=0; i<n; i++) //Everybody should try to find a chair. if(! foundChair[i] ) { if(findChair[i]) { somethingChanged=true; sum++; } } if(!somethingChanged) break; } return sum; }
I think that when I came up with that algorithm it was based on code I've seen from red coders. The chair metaphor makes it easy to remember. I wonder if this algorithm has a name / original author or if it is something that merely materialized in programming competitions out of need.
Anyway, it is not that fast. It is `O(n^3)` :)
No comments :
Post a Comment