In this problem, we need to find the hops of each island from island M. That fits exactly the Breadth First Search (BFS) algorithm introduced in the USACO training pages. The algorithm is summarized as follows:
- Insert M into the queue.
- Get the next island, I from the queue.
- Insert the unmarked neigbors of I into the queue, record their hops (add 1 to I's hop) and mark them.
- If the queue is not empty, go to step 2.
For the example in the problem, the steps can be demonstrated as follows:
mark array
step queue 1 2 3 4 => islands
==== ===== =======
0 1 0
1 2 4 0 1 1 => hopes in each step
2 4 3 0 1 2 1
3 3 0 1 2 1
4 0 1 2 1
Notice that we don't use an array for hops but use the mark array also to record the hops of the islands. While outputting the islands, we need to be careful about the order to be ascending. So, what we need to do is to search the mark array for 0 hops and output the first line, search for 1 hop and output the second line, search for 2 hops and output the third line, and so on... Since we search the islands from left to right, the output will be in ascending order.
Below is an example solution:
#include <iostream>
#include <fstream>
#define MAX 101
using namespace std;
int n, m, mat[MAX][MAX],mark[MAX],que[MAX],front,rear;
int main()
{
//freopen("1.txt", "r", stdin);
cin >> n >> m;
for (int i=1; i <= n; i++)
for (int j=1; j <= n; j++)
cin >> mat[i][j];
que[rear++]=m; // add M into the queue
mark[m]=1; // start the hops from 1 not 0
// since all the islands will be initially 0
// continue until the queue is empty
while (front < rear)
{
// get the next island in the queue
int island=que[front++];
// add all the unmarked neighbors of the island into the queue
for (int i=1; i <= n; i++)
if (!mark[i] && mat[island][i])
que[rear++]=i,mark[i]=mark[island]+1;
}
// start searching the islands with 1 hop, 2 hops, etc...
// until the last island that was in the queue.
for (int i=1; i <= mark[que[rear-1]]; i++)
{
for (int j=1, k=0; j<=n; j++)
// if the hop of the island is equal the current hop
if (mark[j] == i)
{
// be careful when outputting
// if it is not the first island in the line,
// put space after that (k is used for that)
if (k) cout << " ";
cout << j;
k++;
}
cout << endl; // end of line
}
}