最大流模板(Dinic)
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#include<stdio.h>
#include<cstring>
typedef long long int ll;
const ll inf = 2005020600;
using namespace std;
int n,m,s,t;
const int maxn = 520010;
struct edge{
int v,next;
ll f;
}e[maxn];
int head[maxn],tot = 1;
void add(int u,int v,ll f){
e[++tot].v = v;
e[tot].f = f;
e[tot].next = head[u];
head[u] = tot;
}
ll dep[maxn];
int now[maxn];
inline bool bfs(){
for(int i = 1; i <= n; i++)dep[i] = -1;
queue<int>st;
st.push(s);
dep[s] = 0;
now[s] = head[s];//当前弧优化
while(!st.empty()){
int u = st.front();st.pop();
for(int i = head[u]; i ; i = e[i].next){
int v = e[i].v;
if(dep[v] == -1 && e[i].f > 0){
dep[v] = dep[u] + 1;
st.push(v);
now[v] = head[v];//当前弧优化
if(v == t)return 1;
}
}
}
return 0;
}
inline ll dfs(int u,ll flow){
if(u == t)return flow;
ll rest = 0;
for(int i = now[u]; i && flow > 0; i = e[i].next){//当前弧优化
now[u] = i;//当前弧优化
int v = e[i].v;
if((dep[v] == dep[u] + 1) && e[i].f > 0){
ll temp = dfs(v,min(flow,e[i].f));
if(temp == 0)dep[v] = -1;//炸点优化
rest += temp;//通过这个点流出去的流量
flow -= temp;//这个点剩余流流
e[i].f -= temp;
e[i ^ 1].f += temp;
}
}
return rest;//返回一共流出去的流量
}
void maxflow(){
ll ans = 0;
while(bfs()){
ans += dfs(s,(ll)inf);
}
printf("%lld\n",ans);
}
int main(){
scanf("%d%d%d%d",&n,&m,&s,&t);
for(int i = 1; i <= m; i++){
ll w;
int u,v;scanf("%d%d%lld",&u,&v,&w);
add(u,v,w);add(v,u,0);
}
maxflow();
return 0;
}
最小费用最大流模板(bfs+sfpa)
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#include<cstring>
#include<stdio.h>
using namespace std;
const int maxn = 2e5 + 10;
struct edge{
int v,w,f,next;
}e[maxn];
int head[maxn],tot = 1;
void add(int u,int v,int w,int f){
e[++tot].v = v;
e[tot].f = f;
e[tot].w = w;
e[tot].next = head[u];
head[u] = tot;
}
int n,m,s,t;
int pre[maxn],dis[maxn];
bool vis[maxn];
int flow[maxn];
int spfa(){
memset(flow,0,sizeof(flow));
memset(vis,0,sizeof(vis));
memset(dis,0x3f,sizeof(dis));
queue<int>st;
st.push(s);
dis[s] = 0,vis[s] = 1,flow[s] = 1 << 30;
while(!st.empty()){
int u = st.front();st.pop();
vis[u] = 0;
for(int i = head[u]; i ;i = e[i].next){
if(e[i].f <= 0)continue;
if(dis[e[i].v] > e[i].w + dis[u]){
dis[e[i].v] = e[i].w + dis[u];
pre[e[i].v] = i;
flow[e[i].v] = min(flow[u],e[i].f);
if(!vis[e[i].v]){
vis[e[i].v] = 1;
st.push(e[i].v);
}
}
}
}
return dis[t] != 1061109567;
}
void mcmf(){
int maxflow = 0,mincost = 0;
while(spfa()){
maxflow += flow[t];
mincost += flow[t] * dis[t];
int p = t;
while(p != s){
e[pre[p]].f -= flow[t];
e[pre[p] ^ 1].f += flow[t];
p = e[pre[p] ^ 1].v;
}
}
cout<<maxflow<<" "<<mincost<<endl;
}
int main(){
scanf("%d%d%d%d",&n,&m,&s,&t);
for(int i = 1; i <= m; i++){
int u,v,w,f;scanf("%d%d%d%d",&u,&v,&f,&w);
add(u,v,w,f);
add(v,u,-w,0);//反边负权
}
mcmf();
return 0;
}