洛谷 P3381 【模板】最小费用最大流
题目描述
如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用。
输入输出格式
输入格式:
第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。
接下来M行每行包含四个正整数ui、vi、wi、fi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi),单位流量的费用为fi。
输出格式:
一行,包含两个整数,依次为最大流量和在最大流量情况下的最小费用。
输入输出样例
输入样例#1:
4 5 4 3 4 2 30 2 4 3 20 3 2 3 20 1 2 1 30 9 1 3 40 5
输出样例#1:
50 280
说明
时空限制:1000ms,128M
(BYX:最后两个点改成了1200ms)
数据规模:
对于30%的数据:N<=10,M<=10
对于70%的数据:N<=1000,M<=1000
对于100%的数据:N<=5000,M<=50000
样例说明:
如图,最优方案如下:
第一条流为4-->3,流量为20,费用为3*20=60。
第二条流为4-->2-->3,流量为20,费用为(2+1)*20=60。
第三条流为4-->2-->1-->3,流量为10,费用为(2+9+5)*10=160。
故最大流量为50,在此状况下最小费用为60+60+160=280。
故输出50 280。
#include <ctype.h> #include <cstdio> #define Max 50005 #define inf 0x7fffffff void read(int &x) { x=0;bool f=0; register char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; x=f?(~x)+1:x; } struct Edge { int next,to,flow,value; }edge[Max<<1]; bool vis[Max]; int flow[Max],answer,cost,fa[Max],head[Max],cnt=1,N,M,S,T,dis[Max]; int min(int a,int b) {return a>b?b:a;} void insert(int u,int v,int w,int l) { Edge *now=&edge[++cnt]; now->next=head[u]; now->to=v; now->flow=w; now->value=l; head[u]=cnt; } bool spfa(int s,int t) { for(int i=1;i<=N;i++) {dis[i]=inf;vis[i]=0;flow[i]=inf;} vis[s]=1; dis[s]=0; fa[s]=0; int que[Max],l=0,r=0; que[++r]=s; while(l<r) { int now=que[++l]; vis[now]=0; for(int i=head[now];i;i=edge[i].next) { int v=edge[i].to; if(dis[v]>dis[now]+edge[i].value&&edge[i].flow>0) { dis[v]=dis[now]+edge[i].value; flow[v]=min(flow[now],edge[i].flow); fa[v]=i; if(!vis[v]) { vis[v]=1; que[++r]=v; } } } } return dis[t]<inf; } void dinic(int s,int t) { for(;spfa(s,t);) { int x=flow[t]; for(int i=t;i!=s&&i!=-1;i=edge[fa[i]^1].to) { edge[fa[i]].flow-=x; edge[fa[i]^1].flow+=x; } answer+=x;cost+=x*dis[t]; } } int main() { read(N); read(M); read(S); read(T); for(int u,v,w,f;M--;) { read(u); read(v); read(w); read(f); insert(u,v,w,f); insert(v,u,0,-f); } dinic(S,T); printf("%d %d\n",answer,cost); return 0; }
我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。