先BFS出值为1的地方, 找到距终点哈密顿距离最短的,这些肯定在一条对角线上,斜行递推就行
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <cstring>
#include <vector>
#include <set>
#include <stack>
using namespace std;
#define ll long long
#define maxn 100005
struct qnode
{
int x, y, dis;
qnode()
{
x = 0;
y = 0;
dis = 0;
}
qnode(int x, int y, int dis)
{
this->x = x;
this->y = y;
this->dis = dis;
}
bool operator <(const qnode &r)const
{
return dis>r.dis;
}
};
const int dx[4] = { 0, 0, 1, -1 };
const int dy[4] = { 1, -1, 0, 0 };
int N, M;
char grid[1005][1005];
bool used[1005][1005];
char ans[2005];
priority_queue<qnode> Q2;
queue< pair<int, int> > Q1;
queue<qnode> Q3;
qnode thenext[2005];
int T;
pair<int, int> t1;
qnode t2;
int xx, yy;
int mn;
bool blank;
bool havezero;
int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
scanf("%d", &T);
while (T--)
{
memset(used, 0, sizeof(used));
blank = false;
scanf("%d%d", &N, &M);
for (int i = 0; i < N; ++i)
scanf("%s", grid[i]);
//printf("N %d M %d\n", N, M);
//printf("%d %d %d\n", Q1.empty(), Q2.empty(), Q3.empty());
Q1.push(make_pair(0, 0));
used[0][0] = true;
while (!Q1.empty())
{
t1 = Q1.front();
Q1.pop();
if (grid[t1.first][t1.second] == '1')
{
//printf("is 1 %d %d\n", t1.first, t1.second);
Q2.push(qnode(t1.first, t1.second, abs(N - 1 - t1.first) + abs(M - 1 - t1.second)));
continue;
}
if (t1.first == N - 1 && t1.second == M - 1)
{
blank = true;
break;
}
for (int i = 0; i < 4; ++i)
{
xx = t1.first + dx[i];
yy = t1.second + dy[i];
//printf("make %d %d\n", xx, yy);
if (xx >= 0 && xx < N&&yy >= 0 && yy < M&&used[xx][yy] == false)
{
Q1.push(make_pair(xx, yy));
used[xx][yy] = true;
//printf("in queue %d %d\n", xx, yy);
}
}
}
while (!Q1.empty())
Q1.pop();
if (blank)
{
while (!Q2.empty())
Q2.pop();
printf("0\n");
continue;
}
if (Q2.empty())
mn = M + N - 1;
else
mn = Q2.top().dis;
if (mn == 0)
{
while (!Q2.empty())
Q2.pop();
printf("1\n");
continue;
}
memset(used, 0, sizeof(used));
while (!Q2.empty())
{
t2 = Q2.top();
Q2.pop();
if (t2.dis > mn)
break;
Q3.push(qnode(t2.x, t2.y, 0));
used[t2.x][t2.y] = true;
}
while (!Q2.empty())
Q2.pop();
//printf("1Q2 %d\n", Q2.empty());
havezero = false;
int pos = 0;
int nowdis = 0;
ans[nowdis] = '1';
while (1)
{
pos = 0;
havezero = false;
while (!Q3.empty())
{
t2 = Q3.front();
Q3.pop();
if (t2.x + 1 < N&&t2.y < M&&used[t2.x + 1][t2.y] == false)
{
thenext[pos++] = qnode(t2.x + 1, t2.y, t2.dis + 1);
if (grid[t2.x + 1][t2.y] == '0')
havezero = true;
used[t2.x + 1][t2.y] = true;
}
if (t2.x < N&&t2.y + 1 < M&&used[t2.x][t2.y + 1] == false)
{
thenext[pos++] = qnode(t2.x, t2.y + 1, t2.dis + 1);
if (grid[t2.x][t2.y + 1] == '0')
havezero = true;
used[t2.x][t2.y + 1] = true;
}
}
++nowdis;
if (havezero)
{
for (int i = 0; i < pos; ++i)
{
if (grid[thenext[i].x][thenext[i].y] == '0')
Q3.push(thenext[i]);
}
ans[nowdis] = '0';
}
else
{
for (int i = 0; i < pos; ++i)
{
Q3.push(thenext[i]);
}
ans[nowdis] = '1';
}
if (nowdis >= mn)
{
while (!Q3.empty())
Q3.pop();
break;
}
}
ans[mn + 1] = 0;
//printf("2Q2 %d\n", Q2.empty());
printf("%s\n", ans);
}
//system("pause");
//while (1);
return 0;
}