rt
// Problem: P4015 运输问题
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P4015
// Memory Limit: 250 MB
// Time Limit: 1000 ms
#include<stdio.h>
#include<string.h>
#include<queue>
const int maxn=202,maxm=20200,inf=0x7f7f7f7f;
int s,t,head[maxn],v[maxm],cap[maxm],cost[maxm],nxt[maxm],dist[maxn],cur[maxn],cnt=-1;
bool vis1[maxn],vis2[maxm];
inline void link(int a,int b,int c,int d){
v[++cnt]=b,cap[cnt]=c,cost[cnt]=d,nxt[cnt]=head[a],head[a]=cnt;
v[++cnt]=a,cap[cnt]=0,cost[cnt]=-d,nxt[cnt]=head[b],head[b]=cnt;
}
bool bfs(){
memset(dist,0x7f,sizeof(dist));
memset(vis1,0,sizeof(vis1));
memcpy(cur,head,sizeof(cur));
std::queue<int> q;
for(q.push(s),dist[s]=0,vis1[s]=1;q.size();vis1[q.front()]=0,q.pop())
for(int i=head[q.front()];~i;i=nxt[i])
if(cap[i]&&dist[v[i]]>dist[q.front()]+cost[i]){
dist[v[i]]=dist[q.front()]+cost[i];
if(!vis1[v[i]])
q.push(v[i]),vis1[v[i]]=1;
}
return dist[t]!=0x7f7f7f7f;
}
inline int min(int a,int b){
return a>b?b:a;
}
int mincost;
int dfs(int x=s,int flow=inf){
if(x==t)
return flow;
int f=0,tmp;
vis2[x]=true;
for(int&i=cur[x];~i;i=nxt[i])
if(cap[i]&&(!vis2[v[i]])&&(dist[v[i]]==dist[x]+cost[i])){
tmp=dfs(v[i],min(flow,cap[i])),cap[i]-=tmp,cap[i^1]+=tmp,f+=tmp,mincost+=tmp*cost[i];
if(!(flow-=tmp))
break;
}
vis2[x]=false;
if(!f)
dist[x]=0;
return f;
}
void dinic(int x){
mincost=0;
for(int i=0;i<=cnt;++i)cost[i]*=x;
for(;bfs();)
for(;dfs(););
for(int i=0;i<=cnt;++i)cost[i]/=x;
}
int a[maxn],b[maxn];
int main(){
int n,m,w;
scanf("%d%d",&n,&m),s=0,t=n+m+1;
for(int i=1;i<=n;++i)scanf("%d",a+i);
for(int i=1;i<=m;++i)scanf("%d",b+i);
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j){
scanf("%d",&w);
link(i,n+j,min(a[i],b[j]),w);
}
for(int i=1;i<=n;++i)link(s,i,a[i],0);
for(int i=1;i<=m;++i)link(n+i,t,b[i],0);
dinic(1);
printf("%d\n",mincost);
dinic(-1);
printf("%d\n",-mincost);
return 0;
}
感觉建图应该没写错吧