<p>You are given a <strong>positive</strong> integer <code>k</code>. You are also given:</p>

<ul>
	<li>a 2D integer array <code>rowConditions</code> of size <code>n</code> where <code>rowConditions[i] = [above<sub>i</sub>, below<sub>i</sub>]</code>, and</li>
	<li>a 2D integer array <code>colConditions</code> of size <code>m</code> where <code>colConditions[i] = [left<sub>i</sub>, right<sub>i</sub>]</code>.</li>
</ul>

<p>The two arrays contain integers from <code>1</code> to <code>k</code>.</p>

<p>You have to build a <code>k x k</code> matrix that contains each of the numbers from <code>1</code> to <code>k</code> <strong>exactly once</strong>. The remaining cells should have the value <code>0</code>.</p>

<p>The matrix should also satisfy the following conditions:</p>

<ul>
	<li>The number <code>above<sub>i</sub></code> should appear in a <strong>row</strong> that is strictly <strong>above</strong> the row at which the number <code>below<sub>i</sub></code> appears for all <code>i</code> from <code>0</code> to <code>n - 1</code>.</li>
	<li>The number <code>left<sub>i</sub></code> should appear in a <strong>column</strong> that is strictly <strong>left</strong> of the column at which the number <code>right<sub>i</sub></code> appears for all <code>i</code> from <code>0</code> to <code>m - 1</code>.</li>
</ul>

<p>Return <em><strong>any</strong> matrix that satisfies the conditions</em>. If no answer exists, return an empty matrix.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2022/07/06/gridosdrawio.png" style="width: 211px; height: 211px;" />
<pre>
<strong>Input:</strong> k = 3, rowConditions = [[1,2],[3,2]], colConditions = [[2,1],[3,2]]
<strong>Output:</strong> [[3,0,0],[0,0,1],[0,2,0]]
<strong>Explanation:</strong> The diagram above shows a valid example of a matrix that satisfies all the conditions.
The row conditions are the following:
- Number 1 is in row <u>1</u>, and number 2 is in row <u>2</u>, so 1 is above 2 in the matrix.
- Number 3 is in row <u>0</u>, and number 2 is in row <u>2</u>, so 3 is above 2 in the matrix.
The column conditions are the following:
- Number 2 is in column <u>1</u>, and number 1 is in column <u>2</u>, so 2 is left of 1 in the matrix.
- Number 3 is in column <u>0</u>, and number 2 is in column <u>1</u>, so 3 is left of 2 in the matrix.
Note that there may be multiple correct answers.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> k = 3, rowConditions = [[1,2],[2,3],[3,1],[2,3]], colConditions = [[2,1]]
<strong>Output:</strong> []
<strong>Explanation:</strong> From the first two conditions, 3 has to be below 1 but the third conditions needs 3 to be above 1 to be satisfied.
No matrix can satisfy all the conditions, so we return the empty matrix.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>2 &lt;= k &lt;= 400</code></li>
	<li><code>1 &lt;= rowConditions.length, colConditions.length &lt;= 10<sup>4</sup></code></li>
	<li><code>rowConditions[i].length == colConditions[i].length == 2</code></li>
	<li><code>1 &lt;= above<sub>i</sub>, below<sub>i</sub>, left<sub>i</sub>, right<sub>i</sub> &lt;= k</code></li>
	<li><code>above<sub>i</sub> != below<sub>i</sub></code></li>
	<li><code>left<sub>i</sub> != right<sub>i</sub></code></li>
</ul>

// https://leetcode.com/problems/build-a-matrix-with-conditions/

#include <memory_resource>

static const auto s_initialize = [] { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cout.tie(nullptr); return nullptr; }();

class Solution {
public:
    Solution()
		: m_polyAlloc( &m_memRsrc )
	{}
    vector<vector<int>> buildMatrix(int k, vector<vector<int>>& rowConditions, vector<vector<int>>& colConditions) {
        return buildMatrix_v1(k, rowConditions, colConditions); // [64, 81] ms, 59.41 MB.
    }


private:
    // method 1. TopoLogicSort.
    // O( k^2 + V + E ).
    //
    vector<vector<int>> buildMatrix_v1(const int k, const vector<vector<int>>& rowConditions, const vector<vector<int>>& colConditions) {
        using neighbors_vec_t = std::pmr::vector< int >;
        using graph_edges_t = std::pmr::vector< neighbors_vec_t >;
        using idx_vec_t = std::pmr::vector< int >;
        //
        const auto tFunPrepare = [=] (graph_edges_t& rGraph, const vector<vector<int>>& vReq) -> void {
            rGraph.clear();
            rGraph.resize(k + 1);
            for (const auto& req: vReq) {
                rGraph[ req[1] ].emplace_back( req[0] );
            }
        };
        //
        enum class vertex_state_t
        {
            Unvisited = 0
            , Processing
            , Visited
        };
        using vertex_state_vec_t = std::pmr::vector< vertex_state_t >;
        //
        std::function< bool(idx_vec_t&, int&, vertex_state_vec_t&, const int, const graph_edges_t&) > tDfs;
        tDfs = [=, &tDfs] (idx_vec_t& rvIdx, int& rPos, vertex_state_vec_t& rvState, const int i, const graph_edges_t& rcGraph) -> bool {
            rvState[i] = vertex_state_t::Processing;
            for (const int ni: rcGraph[i]) {
                const auto niState = rvState[ni];
                if (vertex_state_t::Unvisited == niState) {
                    if ( !tDfs(rvIdx, rPos, rvState, ni, rcGraph) )
                        return false;
                } else if (vertex_state_t::Processing == niState) {
                    return false;
                }
            }
            rvState[i] = vertex_state_t::Visited;
            rvIdx[i] = rPos;
            ++rPos;
            return true;
        };
        const auto tTopoLogicSort = [=, &tDfs] (idx_vec_t& rvIdx, const graph_edges_t& rcGraph) -> bool {
            rvIdx.resize(k + 1);
            vertex_state_vec_t vState( k + 1, m_polyAlloc );
            int pos = 0;
            for (int i = 1; i <= k; ++i) {
                if (vertex_state_t::Unvisited == vState[i]) {
                    if ( !tDfs(rvIdx, pos, vState, i, rcGraph) )
                        return false;
                }
            }
            return true;
        };
        //
        std::vector< std::vector<int> > vvRes;
        graph_edges_t tGraph( m_polyAlloc );
        tFunPrepare(tGraph, rowConditions);
        idx_vec_t vRowIdx( m_polyAlloc );
        if ( !tTopoLogicSort(vRowIdx, tGraph) )
            return vvRes;
        tFunPrepare(tGraph, colConditions);
        idx_vec_t vColIdx( m_polyAlloc );
        if ( !tTopoLogicSort(vColIdx, tGraph) )
            return vvRes;
        //
        vvRes.resize( k );
        for (auto& vRes: vvRes) {
            vRes.resize( k );
        }
        for (int i = 1; i <= k; ++i) {
            vvRes[ vRowIdx[i] ][ vColIdx[i] ] = i;
        }
        return vvRes;
    }

private:
	std::pmr::unsynchronized_pool_resource m_memRsrc;
	std::pmr::polymorphic_allocator<> m_polyAlloc;
};


59292