inlineintmin(constint x, constint y){return x < y ? x : y;} constint INF = 1e9; constint dx[] = {-1, 1, 0, 0}; constint dy[] = {0, 0, -1, 1}; int f[240][1 << 5], c[240][240], rnd[240], n, m, k, ans; bool mark[240]; std::queue<int> Q;
voidspfa(constint S){ while (Q.size()) { intu(Q.front()); Q.pop(); mark[u] = false; for (intk(0); k <= 3; ++ k) { int tx(u / m + dx[k]), ty(u % m + dy[k]); if (tx < 0 || ty < 0 || n <= tx || m <= ty) continue; if (c[tx + 1][ty + 1] == -1) continue; intpos(tx * m + ty); if (f[u][S] + 1 < f[pos][S]) { f[pos][S] = f[u][S] + 1; if (!mark[pos]) Q.push(pos), mark[pos] = true; } } } }
voidSteiner(){ for (intS(1); S < 1 << k; ++ S) { for (inti(0); i < n * m; ++ i) if (c[i / m + 1][i % m + 1] != -1) { for (intS0(S & S - 1); S0; S0 = S0 - 1 & S) if (f[i][S] > f[i][S0] + f[i][S ^ S0]) f[i][S] = f[i][S0] + f[i][S ^ S0] - 1; if (f[i][S] < INF) Q.push(i), mark[i] = true; } spfa(S); } }
voidwork(){ memset(f, 0x3f, sizeof f); for (inti(1); i <= n; ++ i) for (intj(1); j <= m; ++ j) if (c[i][j] != -1) rnd[c[i][j]] = rand() % k; for (inti(1); i <= n; ++ i) for (intj(1); j <= m; ++ j) if (c[i][j] != -1) f[(i - 1) * m + j - 1][1 << rnd[c[i][j]]] = 1; Steiner(); for (inti(0); i < n * m; ++ i) ans = min(ans, f[i][(1 << k) - 1]); }
intmain(){ srand(time(NULL)); int T; scanf("%d", &T); while (T --) { ans = INF; scanf("%d%d%d", &n, &m, &k); for (inti(1); i <= n; ++ i) for (intj(1); j <= m; ++ j) scanf("%d", &c[i][j]); for (inti(1); i <= 150; ++ i) work(); printf("%d\n", ans < INF ? ans : -1); } return0; }