题目描述
这是一道模板题。
给定 n 个点,m 条边,给定每条边的容量,求从点 s 到点 t 的最大流。
输入格式
第一行四个整数 n、m、s、t。
接下来的 m 行,每行三个整数 u 、v 、c,表示 u 到 v ,流量为 c 的一条边。
输出格式
输出点 s 到点 t 的最大流。
样例
样例输入
7 14 1 7
1 2 5
1 3 6
1 4 5
2 3 2
2 5 3
3 2 2
3 4 3
3 5 3
3 6 7
4 6 5
5 6 1
6 5 1
5 7 8
6 7 7
样例输出
14
数据范围与提示
1≤n≤106,1≤m≤4×106,0≤c≤231−1
use Dijstra, O(fVlogE)
#include <stdio.h>
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
//#include <unordered_map>
//#include <unordered_set>
#include <vector>
using namespace std;
#define mp make_pair
#define pb push_back
#define se second
#define fi first
#define rep(i, n) for(int i = 0; i < n; ++i)
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair<int, int> pii;
const int MOD = (int)1e9 + 7;
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const db PI = acos(-1.0);
const db EPS = 1e-10;
/*
const int MAXS = 64 * 1024 * 1024;
char buf[MAXS], *ch;
void read(int &x) {
int t = 1;
while(*ch <= 32) ++ch;
//if(*ch == '-') ++ch, t = -1;
for(x = 0; *ch >= '0'; ++ch) x = x * 10 + *ch - 48;
//x = t * x;
}
void read_init() {
fread(buf, sizeof(char), MAXS, stdin);
ch = buf;
}
*/
const int MAXV = 405;
const int MAXE = 15005;
int V, E;
struct edge{
int to, cap, cost, nxt;
edge() {}
edge(const int _to, const int _cap, const int _cost, const int _nxt) {
to = _to;
cap = _cap;
cost = _cost;
nxt = _nxt;
}
}dat[MAXE<<1];
int head[MAXV], tail;
void add_edge(int from, int to, int cap, int cost) {
dat[tail] = edge(to, cap, cost, head[from]);
head[from] = tail++;
dat[tail] = edge(from, 0, -cost, head[to]);
head[to] = tail++;
}
int pre[MAXV], h[MAXV], dist[MAXV];
int min_cost_flow(int s, int t, int &f) {
int res = 0;
fill(h, h + V, 0);
while(f > 0) {
priority_queue<pii, vector<pii>, greater<pii> > que;
fill(dist, dist + V, INF);
dist[s] = 0;
que.push(pii(0, s));
while(!que.empty()) {
pii p = que.top(); que.pop();
int v = p.se;
if(dist[v] < p.fi) continue;
for(int i = head[v]; ~i; i = dat[i].nxt) {
edge &e = dat[i];
if(e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]) {
dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
pre[e.to] = i;
que.push(pii(dist[e.to], e.to));
}
}
}
if(dist[t] == INF) return res; // return -1
for(int v = 0; v < V; ++v) h[v] += dist[v];
int d = f;
for(int v = t; v != s; v = dat[pre[v]^1].to) {
d = min(d, dat[pre[v]].cap);
}
f -= d;
res += d * h[t];
for(int v = t; v != s; v = dat[pre[v]^1].to) {
dat[pre[v]].cap -= d;
dat[pre[v]^1].cap += d;
}
}
return res;
}
int main()
{
scanf("%d%d", &V, &E);
int s = 0, t = V - 1;
memset(head, 0xff, sizeof(head));
tail = 0;
int x, y, cap, cost;
rep(i, E) {
scanf("%d%d%d%d", &x, &y, &cap, &cost);
add_edge(x - 1, y - 1, cap, cost);
}
int f = INF;
int min_cost = min_cost_flow(s, t, f);
printf("%d %d\n", INF - f, min_cost);
return 0;
}