洛谷 P3381【模板】最小費用最大流
阿新 • • 發佈:2019-03-23
getc isdigit bfs queue struct 依次 就是 pre spfa
題目描述
如題,給出一個網絡圖,以及其源點和匯點,每條邊已知其最大流量和單位流量費用,求出其網絡最大流和在最大流情況下的最小費用。
輸入輸出格式
輸入格式:
第一行包含四個正整數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。
思路:費用流的模板題,就是在最大流中用 spfa或dijkstra等算法來代替,不同的是費用 流在管流量的同時也要管邊權,所以,可以說算是最大流的升級版吧,我目前還只會 spfa版本的,dijkstra的還不太會寫。
代碼:
#include<cstdio> #include<cstring> #include<cctype> #include<queue> #define maxn 5007 using namespace std; int num=1,n,m,head[maxn],pre[maxn],dis[maxn],vis[maxn],maxflow,ans,S,T; const int inf=0x3f3f3f3f; inline int qread() { char c=getchar();int num=0,f=1; for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) num=num*10+c-'0'; return num*f; } struct node { int u,v,f,w,nxt; }e[maxn*20]; inline void ct(int u, int v, int f, int w) { e[++num]=node{u,v,f,w,head[u]}; head[u]=num; } inline bool bfs() { memset(vis,0,sizeof(vis)); memset(dis,0x3f,sizeof(dis)); queue<int>q; q.push(S),dis[S]=0; while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i;i=e[i].nxt) { int v=e[i].v,f=e[i].f; if(dis[v]>dis[u]+e[i].w&&f) { dis[v]=dis[u]+e[i].w; pre[v]=i; if(!vis[v]) { vis[v]=1; q.push(v); } } } } return dis[T]!=inf; } inline void work() { int minn=inf; for(int i=T;i!=S;i=e[pre[i]].u) minn=min(minn,e[pre[i]].f); for(int i=T;i!=S;i=e[pre[i]].u) { e[pre[i]].f-=minn; e[pre[i]^1].f+=minn; ans+=minn*e[pre[i]].w; } maxflow+=minn; } int main() { n=qread(),m=qread(),S=qread(),T=qread(); for(int i=1;i<=m;++i) { int u=qread(),v=qread(),f=qread(),w=qread(); ct(u,v,f,w),ct(v,u,0,-w); } while(bfs()) work(); printf("%d %d\n",maxflow,ans); return 0; }
洛谷 P3381【模板】最小費用最大流