https://www.lydsy.com/JudgeOnline/problem.php?id=1001
一个图,问你花费多少才能把到终点的所有边堵住...
就是求一个最小割,把$(1,1)$和$(n,m)$ 分开,按他所说的建图就行
不过点数和边数需要开到1e6和1e7...
速度..还能接受,不过这个题应该还能转化为反向图上的最短路解决吧?
(以下是AC代码,但是实际上我本机会RE,不知道为什么..)
#include <bits/stdc++.h>
#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pp pair<int,int>
#define rep(ii,a,b) for(int ii=a;ii<=b;ii++)
#define per(ii,a,b) for(int ii=a;ii>=b;ii--)
#define show(x) cout<<#x<<"="<<x<<endl
#define show2(x,y) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl
#define show3(x,y,z) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define showa(a,b) cout<<#a<<'['<<b<<"]="<<b[a]<<endl
using namespace std;
const int maxn=1e6+10;
const int maxm=1e7+10;
const int INF=0x3f3f3f3f;
int casn,n,m,k;
struct node {int to;int cap;int next;}e[maxm];
int ss,tt,head[maxn],nume,dis[maxn];
inline void addx(int a,int b,int c){
e[++nume]=(node){b,c,head[a]};
head[a]=nume;
}
inline void add(int a,int b,int c){
addx(a,b,c);addx(b,a,c);
}
bool bfs(int s=ss,int t=tt){
int top=0,end=1;
int q[maxn];
q[0]=s;
// for(int i=0;i<=t;i++) dis[i]=0;
memset(dis,0,sizeof dis);
dis[s]=1;
while(top!=end){
int now=q[top++];top%=maxn;
for(int i=head[now];i;i=e[i].next){
int to=e[i].to;
if(!dis[to]&&e[i].cap){
dis[to]=dis[now]+1;
if(to==t)break;
q[end++]=to;end%=maxn;
}
}
}
return dis[t];
}
int dfs(int now=ss,int last=INF){
if(now==tt)return last;
int flow=0,det;
for(int i=head[now];i;i=e[i].next){
int to=e[i].to;
if(e[i].cap&&dis[to]==dis[now]+1){
det=dfs(to,min(last-flow,e[i].cap));
flow+=det;
e[i].cap-=det;
e[i^1].cap+=det;
if(flow==last) return last;
}
}
dis[now]=-1;
return flow;
}
inline int read(){
int num=0,flag=1,ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){num=(num<<3)+(num<<1)+ch-'0',ch=getchar();}
return flag*num;
}
int a,b,c;
int main(){
//#define test
#ifdef test
freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
#endif
nume=1;
n=read();m=read();
rep(i,1,n){
rep(j,2,m){
a=read();
add(m*(i-1)+j,m*(i-1)+j-1,a);
}
}
rep(i,2,n){
rep(j,1,m){
a=read();
add(m*(i-1)+j,m*(i-2)+j,a);
}
}
rep(i,2,n){
rep(j,2,m){
a=read();
add(m*(i-1)+j,m*(i-2)+j-1,a);
}
}
ss=1,tt=n*m;
int ans=0;
while(bfs()) ans+=dfs();
printf("%d\n",ans);
#ifdef test
fclose(stdin);fclose(stdout);system("out.txt");
#endif
return 0;
}