题解:
按照行列斜的关系和它们之间的权值建边然后直接跑最大流就OK了
注意是无向边,所以来回两条边的权值应该是一样的
AC代码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#include<ext/rope>
using namespace std;
using namespace __gnu_cxx;
#define LL long long
const int MAXN = 6e6+50;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
int n,m,s,t,tot=1,head[MAXN],to[MAXN],w[MAXN],nxt[MAXN],h[MAXN];
inline void ade(int u,int v,int ww){
to[++tot]=v; w[tot]=ww; nxt[tot]=head[u]; head[u]=tot;
}
inline void add(int u,int v,int w){ ade(u,v,w); ade(v,u,w); }
inline int bfs(){
queue<int> que; que.push(s); memset(h,0,sizeof(h)); h[s]=1;
while(!que.empty()){
int u=que.front(); que.pop();
for(int i=head[u];i;i=nxt[i]){
if(w[i] && !h[to[i]]){
h[to[i]]=h[u]+1; que.push(to[i]);
}
}
}
return h[t];
}
inline int dfs(int x,int f){
if(x==t) return f; int fl=0;
for(int i=head[x];i&&f;i=nxt[i]){
if(w[i] && h[to[i]]==h[x]+1){
int mi=dfs(to[i],min(f,w[i]));
w[i]-=mi; w[i^1]+=mi; fl+=mi; f-=mi;
}
}
if(!fl) h[x]=-1;
return fl;
}
inline int dinic(){
int res=0;
while(bfs()) res+=dfs(s,INF);
return res;
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
#endif // ONLINE_JUDGE
scanf("%d%d",&n,&m); s=1,t=n*m;
for(int i=1;i<=n;i++)
for(int j=1,x;j<=m-1;j++)
scanf("%d",&x),add(j+(i-1)*m,j+1+(i-1)*m,x);
for(int i=1;i<=n-1;i++)
for(int j=1,x;j<=m;j++)
scanf("%d",&x),add(j+(i-1)*m,j+i*m,x);
for(int i=1;i<=n-1;i++)
for(int j=1,x;j<=m-1;j++)
scanf("%d",&x),add(j+(i-1)*m,j+1+i*m,x);
printf("%d\n",dinic());
return 0;
}
Nightmare丶
发布了178 篇原创文章 · 获赞 1 · 访问量 3371
私信
关注