代码参考 https://www.acwing.com/solution/content/26693/
#include <iostream>
#include <vector>
#include <cstdio>
using namespace std;
const int N = 510;
int n, m, x;
vector<int> res;
struct DLX {
DLX *left, *right, *up, *down;
int row, col;
int count;
int ele;
DLX() {
left = right = up = down = nullptr;
row = col = ele = -1;
count = 0;
}
}table[N][N];
void init() {
for(int i = 0; i < n; i++) {
table[i][0].down = &table[i + 1][0];
table[i + 1][0].up = &table[i][0];
table[i][0].row = i, table[i][0].col = 0;
table[i + 1][0].row = i + 1, table[i + 1][0].col = 0;
}
for(int i = 0; i < m; i++) {
table[0][i].right = &table[0][i + 1];
table[0][i + 1].left = &table[0][i];
table[0][i].row = 0, table[0][i].col = i;
table[0][i + 1].row = 0, table[0][i + 1].col = i + 1;
}
}
void insertCol(int row, int col) {
DLX *p = &table[0][col];
while(p) {
DLX *next = p -> down;
if(next == nullptr) break;
else if(next -> row > row) break;
else if(next -> row == row) {
return ;
}
p = next;
}
DLX *cur = &table[row][col];
if(p -> down) p -> down -> up = cur;
cur -> down = p -> down;
p -> down = cur;
cur -> up = p;
table[0][col].count++;
}
void insertRow(int row, int col) {
DLX *p = &table[row][0];
while(p) {
DLX *next = p -> right;
if(next == nullptr) break;
else if(next -> col > col) break;
else if(next -> col == col) return ;
p = next;
}
DLX *cur = &table[row][col];
if(p -> right) p -> right -> left = cur;
cur -> right = p -> right;
p -> right = cur;
cur -> left = p;
}
void add(int ele, int x, int y) {
table[x][y].ele = ele;
table[x][y].row = x;
table[x][y].col = y;
insertCol(x, y);
insertRow(x, y);
}
void remove(DLX *col) {
if(col -> right) col -> right -> left = col -> left;
col -> left -> right = col -> right;
DLX *cur = col -> down;
while(cur) {
int r = cur -> row;
DLX *row = &table[r][0];
while(row) {
if(row -> col != 0) {
table[0][row -> col].count--;
}
if(row -> col == col -> col) {
row = row -> right;
continue;
}
if(row -> down) row -> down -> up = row -> up;
row -> up -> down = row -> down;
row = row -> right;
}
cur = cur -> down;
}
}
void resume(DLX *col) {
DLX *cur = col -> down;
while(cur) {
int r = cur -> row;
DLX *row = &table[r][0];
while(row) {
if(row -> col != 0) {
table[0][row -> col].count++;
}
if(row -> down) row -> down -> up = row;
row -> up -> down = row;
row = row -> right;
}
cur = cur -> down;
}
if(col -> right) col -> right -> left = col;
col -> left -> right = col;
}
bool dfs() {
int maxn = N * N; // 我这里只设置为N + 1会有三个点re,不明白为什么,一列的最大值不是不超过N吗
DLX *p = table[0][0].right, *q = nullptr;
if(p == nullptr) return true;
while(p) {
if(p -> count != -1 && p -> count < maxn) {
maxn = p -> count;
q = p;
}
p = p -> right;
}
remove(q);
{
p = q -> down;
while(p) {
res.push_back(p -> row);
DLX *temp = table[p -> row][0].right;
while(temp) {
if(temp -> col != q -> col) {
remove(&table[0][temp -> col]);
}
temp = temp -> right;
}
if(dfs()) return true;
res.pop_back();
temp = table[p -> row][0].right;
while(temp) {
if(temp -> col != q -> col) {
resume(&table[0][temp -> col]);
}
temp = temp -> right;
}
p = p -> down;
}
}
resume(q);
return false;
}
int main() {
// freopen("in.txt", "r", stdin);
cin >> n >> m;
init();
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
cin >> x;
if(x) add(x, i, j);
}
}
if(dfs()) {
for(int i : res) cout << i << ' ';
puts("");
} else puts("No Solution");
}