题目看起来好像很变态很难的样子,其实就是最小割。。。╮(╯▽╰)╭
#include<iostream>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cassert>
#include<iomanip>
#include<math.h>
#include<cmath>
using namespace std;
const int maxn = 411;
const int end = 410;
const int inf = 0x3f3f3f3f;
const int maxc = 22;
const int dir[2][2] = {{0,1},{1,0}};
struct zz
{
int from;
int to;
int c;
int id;
}zx,tz;
vector<zz>g[maxn];
queue<int>q;
bool inq[maxn];
int cen[maxn];
int n,m,T,a1,a2;
int p[maxc][maxc];
inline int num(int x,int y)
{
return (x-1)*m + y;
}
inline int dx(int temp)
{
return (temp-1)/m + 1;
}
inline int dy(int temp)
{
return (temp-1)%m + 1;
}
inline int inside(int x,int y)
{
if( 1 <= x && x <= n && 1<=y && y<=m )
{
return true;
}
return false;
}
void link (int now,int to,int c,int bc)
{
zx.from = now;
zx.to = to;
zx.c = c;
zx.id = g[zx.to].size();
g[zx.from].push_back(zx);
swap(zx.from,zx.to);
zx.c = bc;
zx.id = g[zx.to].size() - 1;
g[zx.from].push_back(zx);
return ;
}
bool bfs()
{
memset(cen,-1,sizeof(cen));
while(!q.empty())
{
q.pop();
}
cen[0] = 0;
q.push(0);
int now,to;
while(!q.empty())
{
now = q.front();
q.pop();
for(int i=0;i<g[now].size();i++)
{
to = g[now][i].to;
if(g[now][i].c > 0 && cen[to] == -1)
{
cen[to] = cen[now] + 1;
q.push(to);
}
}
}
return cen[end] != -1;
}
int dfs(int flow = inf,int now=0)
{
if(now == end)
{
return flow;
}
int temp,sum=0;
int to;
for(int i=0;i<g[now].size();i++)
{
to = g[now][i].to;
if(flow > sum && cen[to] == cen[now] + 1 && g[now][i].c >0 )
{
temp = dfs(min(flow-sum,g[now][i].c),to);
sum += temp;
g[now][i].c -= temp;
g[to][g[now][i].id].c += temp;
}
}
if(!sum) cen[now] = -1;
return sum;
}
int dinic()
{
int ans = 0;
while(bfs())
{
ans += dfs();
}
return ans;
}
void build()
{
for(int i=0;i<maxn;i++)
{
g[i].clear();
}
int nowx,nowy;
int from,to;
int cp;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
from = num(i,j);
for(int k=0;k<2;k++)
{
nowx = i + dir[k][0];
nowy = j + dir[k][1];
to = num(nowx,nowy);
cp = abs(p[i][j] - p[nowx][nowy]);
if( inside(nowx,nowy) )
{
link(from,to,cp,cp);
}
}
to = end;
cp = abs(a2 - p[i][j]);
link(from,to,cp,0);
to = from;
from = 0;
cp = abs(a1 - p[i][j]);
link(from,to,cp,0);
}
}
return ;
}
int main()
{
cin>>T;
for(int tt=1;tt<=T;tt++)
{
cin>>n>>m>>a1>>a2;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>p[i][j];
}
}
build();
cout<<"Case "<<tt<<":"<<endl;
cout<<dinic()<<endl;
if(tt!=T)
{
cout<<endl;
}
}
return 0;
}