using namespace std;
const int INF = INT_MAX;
//结构体node,有自己的坐标,还有一个距离?
struct Node {
int x, y, distance;
bool operator>(const Node& other) const {
return distance > other.distance;
}
};
int dijkstra(const vector<vector<int>>& grid, const pair<int, int>& start, const pair<int, int>& end) {
//获取n
int n = grid.size();
//创建了一个distance数组
vector<vector<int>> distance(n, vector<int>(n, INF));
//优先队列储存node,数据结构为vector<Node>,以小顶堆的方式
priority_queue<Node, vector<Node>, greater<Node>> pq;
//放入起点
pq.push({ start.first, start.second, 0 });
distance[start.first][start.second] = 0;
while (!pq.empty()) {
Node current = pq.top();
pq.pop();
//如果到达目的地了,就返回距离
if (current.x == end.first && current.y == end.second) {
return current.distance;
}
//方向
int dx[] = { -1, 1, 0, 0 };
int dy[] = { 0, 0, -1, 1 };
//生成四个方向
for (int i = 0; i < 4; i++) {
//下一个方向的坐标
int nx = current.x + dx[i];
int ny = current.y + dy[i];
//没出界
if (nx >= 0 && nx < n && ny >= 0 && ny < n) {
//grid存的是值,newDistance
int newDistance = current.distance + grid[nx][ny];
//处理其它三个方向的坐标,如果其它三个方向的坐标小于这个distance
if (newDistance < distance[nx][ny]) {
distance[nx][ny] = newDistance;
pq.push({ nx, ny, newDistance });
}
}
}
}
return -1; // Should not reach here if a valid path exists
}
int main() {
int t;
cin >> t;
//循环次数
while (t--) {
//几阶矩阵
int n;
cin >> n;
//地图
vector<vector<int>> grid(n, vector<int>(n));
//起始坐标和终点坐标
pair<int, int> start, end;
//输入地图
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> grid[i][j];
if (grid[i][j] == 0) {
if (start.first == 0 && start.second == 0) {
start = { i, j };
}
else {
end = { i, j };
}
}
}
}
//传入了地图,起始坐标,终点坐标
int result = dijkstra(grid, start, end);
cout << result << endl;
}
return 0;
}