Both the stated symmetry of your biadjacency matrix A, and your intention to use topological sorting to isolate a bipartite structure in the graph - point out that you are in fact referring to an indirected, acyclic, graph - i.e., a tree.
(A being symmetric explicitly says that if you have an edge from x to y, you must have an edge from y to x - hence, directedness becomes meaningless).
Assuming that is indeed your intention:
(1) As for any indirected graph, you can immediately settle for around 0.5*(n^2) (exactly: n(n-1)/2), by storing just the upper triangle of the adjacency matrix.
(2) Suppose you must store just B.
You must first identify disjoint subsets, say R & S, each having no internal edges. Topological sorting is a plausible option - in a tree, it amounts to picking a root and labeling vertices by being on even/odd levels above the root (in contrast with common visualizations, I prefer to think of a tree as actually growing above its root..). I understand from your question that you're comfortable with that, so I won't even give pseudo-code.
Next you need to re-label the vertices so that all R's vertices come first, and all S's vertices follow:
Allocate NewLabels(r + s);
CurRSize = 0;
CurSSize = 0;
for each (TreeLevel)
if #CurLevel is even // append to R vertices
NewLabels(CurRSize : CurRsize + CurLevelSize - 1) = CurLevelVertexNums;
CurRSize += CurLevelSize;
else // append to S vertices
NewLabels(r+s - (CurSSize+CurLevelSize) : r+s - (CurSSize + 1) = CurLevelVertexNums;
CurSSize += CurLevelSize;
(Some optimizations immediately come to mind, but they're not important here).
Then, you can serially scan the graph edges, and store them as entries into the r x s matrix B, indexed by the new vertex labels:
Allocate B(r,s);
Zero(B);
for each (edge = x<-->y)
i = NewLabels(x);
j = NewLabels(y) - r; // must adjust, to index just B
B(i,j) = 1;
HTH.