在最大流的基础上把BFS换成SPFA即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100050;
const int INF = 0x3f3f3f3f;
int head[maxn];
bool vis[maxn];
int dis[maxn];
int flow[maxn];
int n,m,s,t;
struct edge{
int v,f,c,next;
}e[maxn];
struct node{
int id;
int v;
}pre[maxn];
int cnt;
void init(){
cnt=0;
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
}
void addedge(int u,int v,int f,int c){
e[cnt].v=v;
e[cnt].f=f;
e[cnt].c=c;
e[cnt].next=head[u];
head[u]=cnt++;
}
bool spfa()
{
memset(dis,INF,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(flow,INF,sizeof(flow));
queue<int>que;
que.push(s);dis[s]=0;
while(!que.empty())
{
int u=que.front();que.pop();
vis[u]=0;
for(int i=head[u];i+1;i=e[i].next)
{
int v=e[i].v,di=e[i].c,c=e[i].f;
if(c&&dis[v]>dis[u]+di)
{
dis[v]=dis[u]+di;
pre[v].id=i;
pre[v].v=u;//存v点的父亲u
flow[v]=min(c,flow[u]);
if(!vis[v])
{
que.push(v);vis[v]=1;
}
}
}
}
return flow[t]!=flow[s];
}
void MCMF()
{
int mf=0;
int mc=0;
while(spfa())
{
mf+=flow[t];//更新最大流
mc+=flow[t]*dis[t];//更新最小费用
for(int u=t;u!=s;u=pre[u].v)//从T返回沿路径修改剩余容量
{
int v=pre[u].id;
e[v].f-=flow[t];//正边减掉增广量
e[v^1].f+=flow[t];//反边减掉增广量
}
}
printf("%d %d\n",mf,mc);
}
int main(){
init();
cin>>n>>m>>s>>t;
int u,v,f,c;
for(int i=1;i<=m;i++){
cin>>u>>v>>f>>c;
addedge(u,v,f,c);
addedge(v,u,0,-c);
}
MCMF();
return 0;
}