P3381 【模板】最小费用最大流
【题意】
最小费用最大流
【分析】
用spfa代替bfs,然后用EK算法增广即可
【代码】
#include<bits/stdc++.h> using namespace std; int n,m,s,t; const int maxn=5e3+5; const int inf=pow(2,31)-1; const int maxm=5e4+5; struct edge { int u,to,nxt,v,w; }e[maxm<<1]; int head[maxn],cnt=1; void add(int x,int y,int a,int b) { e[++cnt].nxt=head[x]; e[cnt].to=y; e[cnt].u=x; e[cnt].v=a; e[cnt].w=b; head[x]=cnt; } int vis[maxn],dis[maxn],pre[maxn]; bool spfa() { memset(vis,0,sizeof(vis)); memset(dis,0x3f,sizeof(dis)); memset(pre,-1,sizeof(pre)); dis[s]=0; queue <int> q; q.push(s); vis[s]=1; while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i!=-1;i=e[i].nxt) { if(!e[i].v) continue; int to=e[i].to; if(dis[u]+e[i].w<dis[to]) { dis[to]=dis[u]+e[i].w; pre[to]=i; if(!vis[to]) { q.push(to); vis[to]=1; } } } } return (pre[t]!=-1); } void mcmf() { int ans=0,res=0; while(spfa()) { int flow=inf; for(int i=t;i!=s;i=e[pre[i]^1].to) flow=min(flow,e[pre[i]].v); for(int i=t;i!=s;i=e[pre[i]^1].to) { e[pre[i]].v-=flow; e[pre[i]^1].v+=flow; res+=e[pre[i]].w*flow; } ans+=flow; } printf("%d %d\n",ans,res); } int main() { scanf("%d%d%d%d",&n,&m,&s,&t); int x,y,z,w; memset(head,-1,sizeof(head)); for(int i=1;i<=m;i++) { scanf("%d%d%d%d",&x,&y,&z,&w); add(x,y,z,w); add(y,x,0,-w); } mcmf(); return 0; }