Minor bug in C++ dfs question in a big test case - c++

I am solving a question on leetcode, my answer passed 123 test cases and failed on one. I can't figure out my problem because the test case is large and my solution works with every small testcase I could think of. The discussion section of leetcode wasn't helpful so I thought id try here.
question is: "You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water.
Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells).
The island doesn't have "lakes" (water inside that isn't connected to the water around the island). One cell is a square with side length 1. The grid is rectangular, width and height don't exceed 100. Determine the perimeter of the island."
example test case: [[0,1,0,0],
[1,1,1,0],
[0,1,0,0],
[1,1,0,0]]
Output: 16
https://leetcode.com/problems/island-perimeter/
my solution
class Solution {
public:
bool dfs(unordered_set<string> & set, vector<vector<int>> &grid, int x,int y, int& count)
{
if(x>=grid.size()||y>=grid[0].size()||y<0||x<0)
{
return false; // false means current coordinate is not an island piece
}
string loco=to_string(x)+to_string(y);
if(grid[x][y]==0)
return false;
if(set.find(loco)!=set.end())
{
return true;
}
set.insert(loco); //insert island piece to visited pieces
int temp=4-(dfs(set,grid,x+1,y,count)+dfs(set,grid,x-1,y,count)+dfs(set,grid,x,y+1,count)+dfs(set,grid,x,y-1,count)); //subtract the number of adjecent island pieces
count+=temp;
return true;
}
int islandPerimeter(vector<vector<int>>& grid) {
unordered_set<string>set;
int count=0;
for(int i=0 ;i <grid.size();i++)
{
for(int j=0;j<grid[0].size();j++)
{
if(grid[i][j]==1) //find the first piece of island and run DFS
{
dfs(set,grid,i,j,count);
return count;
}
}
}
return count;
}
};
I have checked the discussion section of leetcode but most of the solutions were iterative and didn't use DFS like i did. I am trying to understand what the problem is with my solution.
The testcase that failed is :
[[0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,1,0,1,1,0],
[0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,1,0,0,1,0],
[0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,1,0],
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
[1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
[0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],
[0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
[0,0,1,1,1,0,1,1,1,1,1,1,0,0,1,1,0,0,0,0],
[0,0,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0],[0,0,1,1,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0]]
expected output=128
my output= 125

You are using string loco=to_string(x)+to_string(y); as the key for your std::set. Clearly, if x = 11 and y = 1 then the key is 111, just as when x = 1 and y = 11, which can break your algorithm.
Using a std::string as the set key is an unusual choice in the first place. I would recommend using std::pair<int, int> instead. Using your own type dedicated for this purpose (struct Coordinate { int x, y; };) would be even clearer but would need some additional boilerplate (namely operator<) to work with std::set, whereas std::pair has this out-of-the-box.

Related

Is this Union Find really O(n) as they claim?

I am solving a problem on LeetCode:
Given an unsorted array of integers nums, return the length of the longest consecutive elements sequence. You must write an algorithm that runs in O(n) time. So for nums = [100,4,200,1,3,2], the output is 4.
The Union Find solution to solve this is as below:
class Solution {
public:
vector<int> parent, sz;
int find(int i) {
if(parent[i]==i) return i;
return parent[i]=find(parent[i]);
}
void merge(int i, int j) {
int p1=find(i);
int p2=find(j);
if(p1==p2) return;
if(sz[p1]>sz[p2]) {
sz[p1]+=sz[p2];
parent[p2]=p1;
} else {
sz[p2]+=sz[p1];
parent[p1]=p2;
}
}
int longestConsecutive(vector<int>& nums) {
sz.resize(nums.size(),1);
parent.resize(nums.size(),0);
iota(begin(parent),end(parent),0);
unordered_map<int, int> m;
for(int i=0; i<nums.size(); i++) {
int n=nums[i];
if(m.count(n)) continue;
if(m.count(n-1)) merge(i,m[n-1]);
if(m.count(n+1)) merge(i,m[n+1]);
m[n]=i;
}
int res=0;
for(int i=0; i<parent.size(); i++) {
if(parent[i]==i && sz[i]>res) {
res=sz[i];
}
}
return res;
}
};
This gets accepted by the OJ (Runtime: 80 ms, faster than 76.03% of C++ online submissions for Longest Consecutive Sequence), but is this really O(n), as claimed by many answers, such as this one? My understanding is that Union Find is an O(NlogN) algorithm.
Are they right? Or, am I missing something?
They are right. A properly implemented Union Find with path compression and union by rank has linear run time complexity as a whole, while any individual operation has an amortized constant run time complexity. The exact complexity of m operations of any type is O(m * alpha(n)) where alpha is the inverse Ackerman function. For any possible n in the physical world, the inverse Ackerman function doesn't exceed 4. Thus, we can state that individual operations are constant and algorithm as a whole linear.
The key part for path compression in your code is here:
return parent[i]=find(parent[i])
vs the following that doesn't employ path compression:
return find(parent[i])
What this part of the code does is that it flattens the structure of the nodes in the hierarchy and links each node directly to the final root. Only in the first run of find will you traverse the whole structure. The next time you'll get a direct hit since you set the node's parent to its ultimate root. Notice that the second code snippet works perfectly fine, but it just does redundant work when you are not interested in the path itself and only in the final root.
Union by rank is evident here:
if(sz[p1]>sz[p2]) {...
It makes sure that the node with more children becomes the root of the node with less children. Therefore, less nodes need to be reassigned a new parent, hence less work.
Note: The above was updated and corrected based on feedback from #Matt-Timmermans and #kcsquared.

Why my minimax is not working

I already have tried to modify my algorithm to work better, but I haven't achieved any result. My problem is that after the first moves, if I have, for example:
XX.
OO.
...
The Computer, instead of choosing 0 2, choses for example 1 2 and sometimes tries to go for position it can't.
My code:
#include "game.hpp"
pair<int,int> winner;
int m = INT_MAX;
pair<int,int> game::minimax(State ini) {
int v = maxValue(ini);
cout << v << endl;
return winner;
}
int game::maxValue(State u){
int check = u.getUtility();
if( check % 700 == 0 ) {
if( u.moves < m ) {
winner = u.move;
m = u.moves;
}
return check;
}
int v = INT_MIN;
u.makeDescendents();
while( !u.ls.empty() ) {
v = max(v,minValue(u.ls.front()));
u.ls.pop_front();
}
return v;
}
int game::minValue(State u) {
int check = u.getUtility();
if( check % 700 == 0 )
return check;
int v = INT_MAX;
u.makeDescendents();
while( !u.ls.empty() ) {
v = min(v,maxValue(u.ls.front()));
u.ls.pop_front();
}
return v;
}
For you can help me better I will make clear the meaning of some variables:
winner: is the position the computer will move
u.moves: is the depth on the search tree , for root is 0
m: supposed to save the less depth state solution , for that way filter solutions and computer must play the move more close of solution.
check: save utility value at this moment for known if is a terminal state
utility for win is 700 for tie is 0 and for defeat is -700
u.ls: list of children states
Something else , I think use m and winner global and return a global on minimax is a poor solution , do you can see some way to improve this?
Thanks very much.
First things first, what does u.getUtility() return if the state is not terminal? If it returns 0, well then 0 % 700 == 0 is true, so it's just finding the first move it expanded and selecting it. Since I can't see the u.makeDescendents() algorithm, I can't rule this out.
If that's not the case, then almost certainly your u.getUtility() function is making the assumption that it is only ever being called for the same max player. i.e. It's returning 700 if X wins and -700 if X loses. If you're running both sides through the same minimax, then when you evaluate O as max, it's still trying to find a win for X because that's the only time it will see the evaluation as a win.
If this is the case, the fix is simple, determine which player's turn it is from the state and return the win/loss evaluation as if it were that player (which is typically always a loss in TicTacToe because you cannot make a move which loses you the game, you can only win by making a move and the previous player made the last move).
If neither of these suggestions solve the problem, the typical way to debug minimax problems is to step through the game tree one level deep at a time, exploring the path that is returning known invalid evaluations until you find the point at which is generates an incorrect value. Then you have to inspect it as to find out why. This is trivial for small games like tic tac toe, because it only goes 9 levels deep and you can get a perfect minimax value, but for any non trivial game, you generally have to look at your evaluation function to determine where the discrepancy is occurring.

How to develop recursive function to interesting game . Recursive Challenge

i am developing a kid´s game.
It consists in
3 Tags
6 sacks
Each sack has one secret fruit inside:Bananas or Tomatoes
The first step is to reveal one sack, for example imagine we reveal sack 2 and it is a T(Tomato)
Now the rule is that you have to assign Tags to Sacks , following the rule that no of to sacks has above a correct Tag
So we start to assign tags to sacks.
And finally:
I don´t know how to develop a recursive function that checks the validity of each movement. I have tried a lot of functions but it ´s becoming impossible.
I think the best option is to create
Recursive function
Checks if any other Tag could be a possible solution of the sacks revealed.If it finds another tag that fit in the sacks (with future solution possible of course) is Game Over.
Which is the pseudo code of this function?Or you can imagine another way to develop this code??
I am really stuck and I ask here because you are awesome
Don´t forget that the game is looking for any other possible movement to return game over, he wants you to fail!
Here I've got one possible solution without recursion. I know that you requested pseudo code, but I did it in JAVA just to make sure that is working. At least it will give you another direction where to look at.
Let's assume that you have an array that represent all your possible combinations, e.g:
"00" => Apple-Apple
"01" => Apple-Banana
"10" => Banana-Apple
"11" => Banana-Banana
So, let's do the validation to find out if the MOVEMENT is valid.
public class TestCode {
public static String[] stuff = new String[] { "00", "01", "10", "11" };
public static Boolean isMySearchValid = false;
public static void main(String[] args) {
String first = "01"; // my first guess was "01" which is Apple-Banana
isMySearchValid = isValid(first, "11"); // find out if 10 is valid and
// also has not been taken
// already
System.out.println(isMySearchValid);
}
public static Boolean isValid(final String firstGuess, final String newGuess) {
Boolean response = false;
if (firstGuess == newGuess) {
response = false; // Game Over, because the newGuess was already
// taken
//System.out.println(response + " 1");
} else {
for (int i = 0; i < stuff.length; i++) {
if (!stuff[i].contains(firstGuess)) {
if (stuff[i].contains(newGuess)) {
response = true;
System.out.println("VALID: because was found available in emelement : " + i);
break;
}
}
}
}
return response;
}
}
2nd Approach: (Pseudo Code)
#define VALID_MOVE = 1;
#define TAG_ALREADY_EXIST = 2;
#define NOT_FOUND_OR_NOT_VALID = 3;
int isTagValid(sring[] ArrayOfTags, string tagToFind) {
string[] tempArray = NULL;
int response;
if(tempArray != NULL) {
foreach(string str in tempArray) {
if (str == tagToFind) {
response = TAG_ALREADY_EXIST;
}
}
} else {
foreach(string str in ArrayOfTags) {
if (str == tagToFind) {
tempArray.add(tagToFind);
response = VALID_MOVE;
} else {
response = NOT_FOUND_OR_NOT_VALID;
}
}
}
return response;
}
Notice that if you proposes another card to a sack as a gameover situation, the next movements should be able to solve the game succesfully. Is not enough to check the validity of 1 movement, you need to check until the game ends.
You assign the 3rd card (Banana| Tomato) to the 3-4 sacks cause is the only one which satisfies the 2 rules (fruits are the same in sacks/card & card not above sacks).L
Later, we do another move .We move the 1st card (Tomato| Tomato to the 3rd sack because we have to satisfy that the rule of "correct card is never above sacks". If the algorithm is one step only checking, it will says that the correct one is the other possibility=>card 2 (Banana|Banana), so it will show us game over. But what the algorithm doesn´t know is that the game became unsolvable because we have a card above the only sack pending to solve (Tomato|Tomato)
I'm going to assume that you have a fixed, small set of fruits, each with an associated id. The simplest way to implement this would be an enum:
enum Fruit {
APPLE,
PEAR,
BANANA
};
This way, APPLE has the value 0, PEAR is 1, and BANANA is 2. Now you can represent any sack pair or card by an array telling how many occurrences there is of each fruit (each element would tell the number of occurrences of the fruit that corresponds to the index). For example, a card with two apples would be {2, 0, 0}, and a sack pair with apples and bananas would be {1, 0, 1}. For each sack pair, you would also keep track of the "visible" fruits: if the aforementioned sack pair hasn't been opened, we have {0, 0, 0}, and when we have only revealed the apples, we would have {1, 0, 0}.
Now, all you need to do to figure out whether a given card is compatible with what we know about a given sack pair is to check each pair of elements and see if all elements from the sack pair's array is less than or equal to the corresponding element of the card's array. No recursion needed:
bool isCompatible(const vector<int> & card, const vector<int> & sack) {
for (int i = 0; i < card.size(); i++) {
if (card[i] < sack[i])
return false;
}
return true;
}
bool isLegalMove(const vector<int> & movedCard, const vector<vector<int> > & otherCards, const vector<int> & sack) {
if (!isCompatible(movedCard, sack))
return false;
for (int i = 0; i < otherCards.size(); i++) {
if (isCompatible(otherCards[i], sack))
return false;
}
return true;
}
Edit: I still don't quite understand the mechanics of your game, but here's the general approach for simulating possible game moves until the game ends. The code assumes that any move will always make the game progress closer to the end, i.e. that it's not possible to go around in circles (if it were, you'd need additional code to keep track of which game states you've tried out).
I'm assuming that all of your game state is wrapped up in a class called GameState, and that a move can be represented by Move. In your case, you might have two subclasses of Move, namely OpenSack (containing the sack index) and MoveCard (containing the original and final positions of the card being moved). You need a function vector<Move *> generateMoves(GameState &) that can generate the moves that are possible in a given game state (note that if the game state is a "game over", this function should return an empty vector). Move needs an abstract function GameState perform(const GameState &), to be implemented by each subclass, that will actually perform the move and create a new GameState (rather than modifying the existing state) that represents the game state after the move. (In a game with a larger state, it would be better to actually modify the state, and to have a reverse() method that would undo the effects of a move.) Then, the simulation can be implemented like this:
bool isSolvable(const GameState & currentState) {
if (currentState.isValidFinalState())
return true;
vector<Move *> moves = generateMoves(currentState);
for (int i = 0; i < moves.size(); i++) {
GameState stateAfterMove = moves[i]->perform(currentState);
if (isSolvable(stateAfterMove))
return true;
}
return false;
}
This will play out all possible moves (this is feasible only because it's such a "small" game), and if any sequence of moves leads to a valid solution, the function will return true.

Program crashes, Tree too large

I'm trying to answer this problem as an exercise:
here are set of coins of {50,25,10,5,1} cents in a box.Write a program to find the number of ways a 1 dollar can be created by grouping the coins.
My solution involves making a tree with each edge having one of the values above. Each node would then hold a sum of the coins. I could then populate this tree and look for leaves that add up to 100. So here is my code
class TrieNode
{
public:
TrieNode(TrieNode* Parent=NULL,int sum=0,TrieNode* FirstChild=NULL,int children=0, bool key =false )
:pParent(Parent),pChild(FirstChild),isKey(key),Sum(sum),NoChildren(children)
{
if(Sum==100)
isKey=true;
}
void SetChildren(int children)
{
pChild = new TrieNode[children]();
NoChildren=children;
}
~TrieNode(void);
//pointers
TrieNode* pParent;
TrieNode* pChild;
int NoChildren;
bool isKey;
int Sum;
};
void Populate(TrieNode* Root, int coins[],int size)
{
//Set children
Root->SetChildren(size);
//add children
for(int i=0;i<size;i++)
{
TrieNode* child = &Root->pChild[0];
int c = Root->Sum+coins[i];
if(c<=100)
{
child = new TrieNode(Root,c);
if(!child->isKey) //recursively populate if not a key
Populate(child,coins,size);
}
else
child = NULL;
}
}
int getNumKeys(TrieNode* Root)
{
int keys=0;
if(Root == NULL)
return 0;
//increment keys if this is a key
if(Root->isKey)
keys++;
for(int i=0; i<Root->NoChildren;i++)
{
keys+= getNumKeys(&Root->pChild[i]);
}
return keys;
}
int _tmain(int argc, _TCHAR* argv[])
{
TrieNode* RootNode = new TrieNode(NULL,0);
int coins[] = {50,25,10,5,1};
int size = 5;
Populate(RootNode,coins,size);
int combos = getNumKeys(RootNode);
printf("%i",combos);
return 0;
}
The problem is that the tree is so huge that after a few seconds the program crashes. I'm running this on a windows 7, quad core, with 8gb ram. A rough calculation tells me I should have enough memory.
Are my calculations incorrect?
Does the OS limit how much memory I have access to?
Can I fix it while still using this solution?
All feedback is appreciated. Thanks.
Edit1:
I have verified that the above approach is wrong. By trying to build a tree with a set of only 1 coin.
coins[] = {1};
I found that the algorithm still failed.
After reading the post from Lenik and from João Menighin
I came up with this solution that ties both Ideas together to make a recursive solution
which takes any sized array
//N is the total the coins have to amount to
int getComobs(int coins[], int size,int N)
{
//write base cases
//if array empty | coin value is zero or N is zero
if(size==0 || coins[0]==0 ||N==0)
return 0;
int thisCoin = coins[0];
int atMost = N / thisCoin ;
//if only 1 coin denomination
if(size==1)
{
//if all coins fit in N
if(N%thisCoin==0)
return 1;
else
return 0;
}
int combos =0;
//write recursion
for(int denomination =0; denomination<atMost;denomination++)
{
coins++;//reduce array ptr
combos+= getComobs(coins, size-1,N-denomination*thisCoin);
coins--;//increment array ptr
}
return combos;
}
Thanks for all the feedback
Tree solution is totally wrong for this problem. It's like catching 10e6 tigers and then let go all of them but one, just because you need a single tiger. Very time and memory consuming -- 99.999% of your nodes are useless and should be ignored in the first place.
Here's another approach:
notice your cannot make a dollar to contain more than two 50 cents
notice again your cannot make a dollar to contain more than four 25 cent coins
notice... (you get the idea?)
Then your solution is simple:
for( int fifty=0; fifty<3; fifty++) {
for( int quarters=0; quarters<5; quarters++) {
for( int dimes=0; dimes<11; dimes++) {
for( int nickels=0; nickels<21; nickels++) {
int sum = fifty * 50 + quarters * 25 + dimes * 10 + nickels * 5;
if( sum <= 100 ) counter++; // here's a combination!!
}
}
}
}
You may ask, why did not I do anything about single cent coins? The answer is simple, as soon as the sum is less than 100, the rest is filled with 1 cents.
ps. hope this solution is not too simple =)
Ok, this is not a full answer but might help you.
You can try perform (what i call) a sanity check.
Put a static counter in TrieNode for every node created, and see how large it grows. If you did some calculations you should be able to tell if it goes to some insane values.
The system can limit the memory available, however it would be really bizarre. Usually the user/admin can set such limits for some purposes. This happens often in dedicated multi-user systems. Other thing could be having a 32bit app in 64bit windows environment. Then mem limit would be 4GB, however this would also be really strange. Any I don't think being limited by the OS is an issue here.
On a side note. I hope you do realize that you kinda defeated all object oriented programming concept with this code :).
I need more time to analyze your code, but for now I can tell that this is a classic Dynamic Programming problem. You may find some interesting texts here:
http://www.algorithmist.com/index.php/Coin_Change
and here
http://www.ccs.neu.edu/home/jaa/CSG713.04F/Information/Handouts/dyn_prog.pdf
There is a much easier way to find a solution:
#include <iostream>
#include <cstring>
using namespace std;
int main() {
int w[101];
memset(w, 0, sizeof(w));
w[0] = 1;
int d[] = {1, 5, 10, 25, 50};
for (int i = 0 ; i != 5 ; i++) {
for (int k = d[i] ; k <= 100 ; k++) {
w[k] += w[k-d[i]];
}
}
cout << w[100] << endl;
return 0;
}
(link to ideone)
The idea is to incrementally build the number of ways to make change by adding coins in progressively larger denomination. Each iteration of the outer loop goes through the results that we already have, and for each amount that can be constructed using the newly added coin adds the number of ways the combination that is smaller by the value of the current coin can be constructed. For example, if the current coin is 5 and the current amount is 7, the algorithm looks up the number of ways that 2 can be constructed, and adds it to the number of ways that 7 can be constructed. If the current coin is 25 and the current amount is 73, the algorithm looks up the number of ways to construct 48 (73-25) to the previously found number of ways to construct 73. In the end, the number in w[100] represents the number of ways to make one dollar (292 ways).
I really do believe someone has to put the most efficient and simple possible implementation, it is an improvement on lenik's answer:
Memory: Constant
Running time: Considering 100 as n, then running time is about O(n (lg(n))) <-I am unsure
for(int fifty=0; fifty <= 100; fifty+=50)
for(int quarters=0; quarters <= (100 - fifty); quarters+=25)
for(int dimes=0; dimes <= (100 - fifty - quarters); dimes+=10)
counter += 1 + (100 - fifty - quarters - dimes)/5;
I think this can be solved in constant time, because any sequence sum can be represented with a linear formula.
Problem might be infinite recursion. You are not incrementing c any where and loop runs with c<=100
Edit 1: I am not sure if
int c = Root->Sum+coins[i];
is actually taking it beyond 100. Please verify that
Edit 2: I missed the Sum being initialized correctly and it was corrected in the comments below.
Edit 3: Method to debug -
One more thing that you can do to help is, Write a print function for this tree or rather print on each level as it progresses deeper in the existing code. Add a counter which terminates loop after say total 10 iterations. The prints would tell you if you are getting garbage values or your c is gradually increasing in a right direction.

Bipartite matching in graph

I have the following code which is an implementation of BPM (bipartite matching, from graph theory)
#include <iostream>
#include <cstring>
using namespace std;
#define M 128
#define N 128
bool graph[M][N];
bool seen[N];
int matchL[M],matchR[N];
int n=4;
int m=4;
bool bpm(int u){
for(int v=0;v<n;v++) if(graph[u][u])
{
if (seen[v]) continue;
seen[v]=true;
if(matchR[v] <0 || bpm(matchR[v])){
matchL[u]=v;
matchR[v]=u;
return true;
}
}
return false;
}
int main(){
graph[0][1]=1;
graph[0][3]=1;
graph[1][3]=1;
graph[0][2]=1;
memset(matchL,-1,sizeof(matchL));
memset(matchR,-1,sizeof(matchR));
int cnt=0;
// memset(seen,0,sizeof(seen));
for(int i=0;i<m;i++){
memset(seen,0,sizeof(seen));
if(bpm(i)) cnt++;
}
cout<<cnt<<endl;
return 0;
}
The definition of cnt and the purpose of this code are given below.
Given a bipartite graph represented as an m-by-n matrix, where graph[i][j] is true iff there is an edge from pigeon i to hole j, computes the maximum number of pigeons that can find a hole (one per pigeon) and an optimal assignment.
graph[m][n], matchL[n], matchR[m] and seen[m] are global arrays.
main() initializes matchL[] and matchR[] to -1 in all components.
main() does a loop over all pigeons i and in each iteration
clears seen[] to 0 in all components
calls bpm(i) and increments the maxflow counter
bpm(i) returns true iff pigeon i can be assigned a hole
cnt contains the number of happy pigeons.
In my case, cnt's value is output as 0. Does this graph algorithm work correctly or have I made some error?
Either your initialization is faulty or this condition in bpm() is faulty:
if (graph[u][u])
There is no element of graph on the diagonal which is set true, so bpm() always fails completely. It is also not clear why you'd be needing to test the diagonal alone. Maybe it should be if (graph[u][v]), or maybe something else.
(Your indentation leaves somewhat to be desired; it is extremely aconventional to put an if condition such as this on the same line as a for loop control. Incidentally, the initialization of matchL and matchR only works on 2's-complement machines.)