1. 程式人生 > >【模板】最小費用最大流

【模板】最小費用最大流

tar getchar print lin problem ron n) std mon

https://www.luogu.org/problemnew/show/3381

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstdlib>

using namespace std;
const int N = 1e4 + 10;//dian
const int NN = 1e5 + 10;//bian
const int INF = 9999999; 

int head[N], dis[N], belong[N];
bool vis[N]; int n, m, S, T, now = 1; int now_flow, ans_flow, ans_mon; struct Node{ int u, v, flow, money, nxt; }E[NN]; queue <int> Q; inline int read() { int x = 0, f = 1; char c = getchar(); while(c < 0 || c > 9) { if(c == -) f
= -1; c = getchar(); } while(c >= 0 && c <= 9) { x = x * 10 + c - 0; c = getchar(); } return x * f; } inline void add(int u,int v,int cap,int money) { E[now].u = u; E[now].v = v; E[now].flow = cap; E[now].money
= money; E[now].nxt = head[u]; head[u] = now++; } int dfs(int start,int minn) { if(start == S) return minn; int bel = belong[start]; int ret = dfs(E[bel].u, min(minn, E[bel].flow)); if(!E[bel ^ 1].money) { now = bel ^ 1; add(start, E[bel].u, 0, -E[bel].money); } E[bel].flow -= ret; E[bel ^ 1].flow += ret; return ret; } inline void MCMF() { while(1) { for(int i = 1; i <= n; i ++) dis[i] = INF, vis[i] = 0; dis[S] = 0; Q.push(S); while(!Q.empty()) { int topp = Q.front(); Q.pop(); vis[topp] = 0; for(int i = head[topp]; ~ i; i = E[i].nxt) { if(dis[E[i].v] > dis[topp] + E[i].money && E[i].flow) { dis[E[i].v] = dis[topp] + E[i].money; belong[E[i].v] = i; if(!vis[E[i].v]) { vis[E[i].v] = 1; Q.push(E[i].v); } } } } if(dis[T] == INF) { printf("%d %d",ans_flow,ans_mon); exit(0); } now_flow = dfs(T, INF); ans_flow += now_flow; ans_mon += now_flow * dis[T]; } } int main() { n = read(); m = read(); S = read(); T = read(); for(int i = 1; i <= n; i ++) head[i] = -1; for(int i = 1; i <= m; i ++) { int u = read(); int v = read(); int cap =read(); int money = read(); now ++; add(u, v, cap, money); } MCMF(); return 0; }

【模板】最小費用最大流