#include<bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxm = 1e5+5;
const int maxn = 1e4+5;
struct Edge{
int next,to,f,w;
}edge[maxm<<1];
int n,m,s,t;
int tot=1;
int head[maxn];
bool inque[maxn];//inque记录是否在队列中
int dis[maxn],pre[maxn],maxf[maxn];//dis用于最短路 pre记录前驱边 maxf记录最小剩余容量
template <typename T>inline void read(T& t){
char c=getchar();t=0;
int f=1;
while(!isdigit(c)){
if(c=='-')f=-1;
c=getchar();
}
while(isdigit(c))t=t*10+c-48,c=getchar();
t=f*t;
}
template <typename T,typename... Args> inline void read(T& t,Args&... args){
read(t);read(args...);
}
void add(int u,int v,int f,int w){
edge[++tot].to=v;edge[tot].w=w;edge[tot].f=f;edge[tot].next=head[u];
head[u]=tot;
edge[++tot].to=u;edge[tot].w=-w;edge[tot].f=0;edge[tot].next=head[v];
head[v]=tot;
}
bool spfa(){
queue<int> q;
q.push(s);
memset(dis,inf,sizeof(dis));
dis[s]=0,inque[s]=true,maxf[s]=inf;//源点流量无限大
while(!q.empty()){
int now=q.front();
q.pop();
inque[now]=false;
for(int i=head[now];i;i=edge[i].next){
int v=edge[i].to;
if(edge[i].f&&dis[now]+edge[i].w<dis[v]){
dis[v]=edge[i].w+dis[now];
pre[v]=i;//记录前驱边
maxf[v]=min(edge[i].f,maxf[now]);//流入v的流量等于 二者的最小值
if(!inque[v]){
inque[v]=true;
q.push(v);
}
}
}
}
return dis[t]<inf?1:0;
}
void MCMF(){
int maxflow=0,mincost=0;
while(spfa()){
int u=t,v;
while(u!=s){
v=pre[u];
edge[v].f-=maxf[t];
edge[v^1].f+=maxf[t];
u=edge[v^1].to;
}
maxflow+=maxf[t];
mincost+=dis[t]*maxf[t];
}
printf("%d %d\n",maxflow,mincost);
}
int main(){
read(n,m,s,t);
for(int i=1;i<=m;i++){
int u,v,f,w;
read(u,v,f,w);
add(u,v,f,w);
}
MCMF();
return 0;
}
洛谷P3381最小费用最大流模板题
最新推荐文章于 2024-07-30 16:29:48 发布