洛谷P4012 深海机器人问题 费用流
Code:
#include<cstdio>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long ll;
const int maxn=1000;
const int INF=1000000+233;
int mapp[20][20];
int s,t,n,cnt=0;
struct Edge{
int from,to,cap,cost;
Edge(int u,int v,int c,int f):from(u),to(v),cap(c),cost(f){}
};
struct MCMF{
vector<Edge>edges;
vector<int>G[maxn];
int d[maxn],inq[maxn],a[maxn],flow2[maxn];
queue<int>Q;
ll ans=0;
int flow=0;
void addedge(int u,int v,int c,int f){
edges.push_back(Edge(u,v,c,f)); //正向弧
edges.push_back(Edge(v,u,0,-f)); //反向弧
int m=edges.size();
G[u].push_back(m-2);
G[v].push_back(m-1);
}
int SPFA(){
for(int i=0;i<=n+4;++i)d[i]=INF,flow2[i]=INF;
d[t]=INF,flow2[t]=INF;
memset(inq,0,sizeof(inq));int f=INF;
d[s]=0,inq[s]=1;Q.push(s);
while(!Q.empty()){
int u=Q.front();Q.pop();inq[u]=0;
int sz=G[u].size();
for(int i=0;i<sz;++i){
Edge e=edges[G[u][i]];
if(e.cap>0&&d[e.to]>d[u]+e.cost){
a[e.to]=G[u][i];
d[e.to]=d[u]+e.cost;
flow2[e.to]=min(flow2[u],e.cap);
if(!inq[e.to]){inq[e.to]=1;Q.push(e.to);}
}
}
}
if(flow2[t]>1||d[t]==INF||d[t]==0)return 0;
f=flow2[t];
flow+=f;
int u=edges[a[t]].from;
edges[a[t]].cap-=f;
edges[a[t]^1].cap+=f;
while(u!=s){
edges[a[u]].cap-=f;
edges[a[u]^1].cap+=f;
u=edges[a[u]].from;
}
ans+=(ll)(d[t])*(-1);
return 1;
}
ll maxflow(){
while(SPFA());
return ans;
}
}op;
int main(){
int p,q,a,b;
scanf("%d%d",&a,&b);
scanf("%d%d",&p,&q);
++p,++q;
n=p*q;
for(int i=0;i<p;++i)
for(int j=0;j<q;++j)mapp[i][j]=++cnt;
for(int i=0;i<p;++i)
for(int j=0;j<q-1;++j){
int c;scanf("%d",&c);
op.addedge(mapp[i][j],mapp[i][j+1],1,-c);
op.addedge(mapp[i][j],mapp[i][j+1],INF,0);
}
for(int i=0;i<q;++i)
for(int j=0;j<p-1;++j){
int c;scanf("%d",&c);
op.addedge(mapp[j][i],mapp[j+1][i],1,-c);
op.addedge(mapp[j][i],mapp[j+1][i],INF,0);
}
s=0,t=500;
for(int i=1;i<=a;++i)
{
int k,x,y;
scanf("%d%d%d",&k,&x,&y);
op.addedge(s,mapp[x][y],k,0);
}
for(int i=1;i<=b;++i){
int k,x,y;
scanf("%d%d%d",&k,&x,&y);
op.addedge(mapp[x][y],t,k,0);
}
printf("%lld",op.maxflow());
return 0;
}