题意
不想讲。
分析
注意到最后一定是左上角全是0右下角全是1的形式,那么答案就是全图的最小割。转成对偶图之后跑一下最短路就好了。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#define mp(x,y) make_pair(x,y)
using namespace std;
typedef pair<int,int> pi;
const int N=251005;
const int inf=1000000000;
int n,s,t,cnt,last[N],dis[N];
bool vis[N];
priority_queue<pi> que;
struct edge{int to,next,w;}e[N*4];
int point(int x,int y)
{
if (!x||y>n) return s;
if (x>n||!y) return t;
return (x-1)*n+y;
}
void addedge(int u,int v,int w)
{
e[++cnt].to=v;e[cnt].w=w;e[cnt].next=last[u];last[u]=cnt;
}
void dij()
{
for (int i=s;i<=t;i++) dis[i]=inf;
dis[s]=0;que.push(mp(0,s));
while (!que.empty())
{
int x=que.top().second;que.pop();
while (!que.empty()&&vis[x]) x=que.top().second,que.pop();
if (vis[x]) break;
vis[x]=1;
for (int i=last[x];i;i=e[i].next)
if (dis[x]+e[i].w<dis[e[i].to])
{
dis[e[i].to]=dis[x]+e[i].w;
que.push(mp(-dis[e[i].to],e[i].to));
}
}
}
int main()
{
scanf("%d",&n);
s=0;t=n*n+1;
for (int i=1;i<=n+1;i++)
for (int j=1;j<=n;j++)
{
int x;scanf("%d",&x);
addedge(point(i-1,j),point(i,j),x);
}
for (int i=1;i<=n;i++)
for (int j=1;j<=n+1;j++)
{
int x;scanf("%d",&x);
addedge(point(i,j),point(i,j-1),x);
}
for (int i=1;i<=n+1;i++)
for (int j=1;j<=n;j++)
{
int x;scanf("%d",&x);
addedge(point(i,j),point(i-1,j),x);
}
for (int i=1;i<=n;i++)
for (int j=1;j<=n+1;j++)
{
int x;scanf("%d",&x);
addedge(point(i,j-1),point(i,j),x);
}
dij();
printf("%d",dis[t]);
return 0;
}