You can start off from an arbitrary starting point for most K times
You can select each hop or jump from the right (x1, y1) to jump to (x2, y2) is the energy consumption Manhattan distance -1
But if the numbers start and end points of the grid of each transition is the same as X, then you will get X energy
Q. Can you jump K times just dance through the whole map (each point is after a) the maximum if possible energy output
Solution: same as first cover strand and the minimum point of each split into the left point and the out-point is a point to the right point is then built according to the meaning of the title edge
It is important how we limit up to take-off times this condition K solution is Add (S, S ', K, 0) and S' towards the right of each point not even a capacity of 1 0 of the cost side
Why is it up to the K chain? Consider the smallest chain cover = | V | - That match after match point number (point) was not the right match is to be regarded as the starting point of a chain so right has not been matched several points we must have a few chain
So we can only have the right to limit K nodes can not be matched
#include<bits/stdc++.h> #define reg register using namespace std; typedef long long ll; typedef int JQK; const int INF = 0x7f7f7f7f; const int MAXN = 505, MAXM = 13000; int Head[MAXN], cur[MAXN], to[MAXM << 1], nxt[MAXM << 1], f[MAXM << 1], ed = 1; int S, T, MAXP, MAXF, pre[MAXN]; JQK lev[MAXN], mono[MAXM << 1]; bool exist[MAXN]; inline void RR(int &x) { char c; bool sign = false; for (c = getchar(); c < '0' || c > '9'; c = getchar()) if (c == '-') { sign = true; } for (x = 0; c >= '0' && c <= '9'; c = getchar()) { x = x * 10 + c - '0'; } sign && (x = -x); } void addedge(int u, int v, int cap, JQK val) { //cout<<u<<" "<<v<<" "<<cap<<" "<<val<<endl; to[++ed] = v; nxt[ed] = Head[u]; Head[u] = ed; f [ed] = ch; mono [-ed] = val; to[++ed] = u; nxt[ed] = Head[v]; Head[v] = ed; f[ed] = 0; mono [-ed] = - 1 * val; return ; } BOOL BFS () { you and; queue<int> q; for (int i = 0; i <= MAXP + 1; i++) { exist[i] = 0; lev [i] = INF; } leu [S] = the [S] = 0 ; q.push(S); while (q.size()) { u = q.front(); q.pop(); exist[u] = false; for (int i = Head[u]; i; i = nxt[i]) if (f[i] && lev[u] + mono[i] < lev[to[i]]) { Lev [to [i]] = lev [u] + mono [i]; pre[to[i]] = i; if (!exist[to[i]]) { exist[to[i]] = true; q.push(to[i]); } } } for (int i = 0; i <= MAXP + 1; i++) { cur[i] = Head[i]; } return lev[T] != INF; } JQK Increase () { JQK delta = INF; for (int i = pre[T]; i; i = pre[to[i ^ 1]]) if (f[i] < delta) { delta = f[i]; } for (int i = pre[T]; i; i = pre[to[i ^ 1]]) { f[i] -= delta; f[i ^ 1] += delta; } MAXF += delta; return delta * lev[T]; } JQK MCMF() { JQK years = 0 ; memset(exist, false, sizeof(exist)); while (BFS()) { years + = Augment (); } return years; } void init(int x123, int y123) { MAXF = 0; for (int i = 0; i <= MAXP; i++) { Head[i] = 0; } ed = 1; S = x123; T = y123; return ; } char f1[15][15]; int ff[15][15]; int num[15][15]; int main() { int TNT; int n, m, K; RR(TNT); for (int cas = 1; cas <= TNT; cas++) { int sum = 0; RR(n), RR(m), RR(K); for (int i = 1; i <= n; i++) { scanf("%s", f1[i] + 1); for (int j = 1; j <= m; j++) { ff [i] [j] = f1 [i] [j] - ' 0 ' ; } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { whether [i] [j] = ++ am; } } MAXP = 2 * sum + 3; init(2 * sum + 2, 2 * sum + 3); addedge(S, S - 1, K, 0); for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { addedge(S, num[i][j], 1, 0); addedge(sum + num[i][j], T, 1, 0); addedge(S - 1, sum + num[i][j], 1, 0); } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { int now = ff[i][j]; for (int k = i + 1; k <= n; k++) { int now2 = ff[k][j]; int add = (now == now2) ? now : 0; addedge(num[i][j], sum + num[k][j], 1, -(add - (k - i - 1))); } for (int k = j + 1; k <= m; k++) { int now2 = ff[i][k]; int add = (now == now2) ? now : 0; addedge(num[i][j], sum + num[i][k], 1, -(add - (k - j - 1))); } } } printf("Case %d : ", cas); if (K < min(n, m)) { printf("-1\n"); continue; } int anser = MCMF(); if (MAXF != sum) { printf("-1\n"); } else { printf("%d\n", -anser); } } return 0; }