P3376 【模板】网络最大流
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 1e6;
const int INF = 1e9;
struct edge
{
int to, next,c; // c: capacity f: flow
} graph[MAXN];
int head[MAXN];
int totlen;
int level[MAXN];
int n, m; // n 点的数量 m 边的数量
int s, t; // s 起点 t 终点
bool dinic_bfs()
{
memset(level, 0, sizeof(level));
queue<int> que;
que.push(s);
level[s] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
for(int i = head[u]; i != -1; i = graph[i].next)
{
int v = graph[i].to;
if(!level[v] && graph[i].c > 0)
{
level[v] = level[u]+1;
que.push(v);
}
}
}
return level[t] != 0;
}
int dinic_dfs(int u, int cpflow) // cpflow: can pass flow 到达u点最大能通过的流量
{
if(u == t) return cpflow; // 到达汇点
int addflow = 0; // u 点到其他点 最多能增广的流量, 最多不能超过cpflow,由前面的边限制
for(int i = head[u]; i != -1 && addflow < cpflow; i = graph[i].next)
{
int v = graph[i].to;
if(level[u]+1 == level[v] && graph[i].c >0)
{
// 这一条路上增广的流量
int tmpadd = dinic_dfs(v, min(cpflow-addflow, graph[i].c));
graph[i].c-= tmpadd; // 正向通过的流量加
graph[i^1].c+= tmpadd; // 反向的流量就得减
addflow += tmpadd;
}
}
return addflow; // 返回这个点都汇点能增广的流量
}
int dinic()
{
int maxflow = 0;
while(dinic_bfs())
{
maxflow += dinic_dfs(s, INF);
}
return maxflow;
}
void addEdge(int u, int v, int c)
{
graph[totlen].to = v;
graph[totlen].next = head[u];
graph[totlen].c = c;
head[u] = totlen++;
graph[totlen].to = u;
graph[totlen].next = head[v];
graph[totlen].c = 0;
head[v] = totlen++;
}
void init()
{
for(int i = 0; i <= n; i++)
head[i] = -1;
totlen = 0;
}
int main()
{
scanf("%d%d", &n, &m);
scanf("%d%d", &s, &t);
init();
for(int i = 1; i <= m; i++)
{
int u, v, c;
scanf("%d%d%d", &u, &v, &c);
addEdge(u, v, c);
}
int ans = dinic();
printf("%d\n",ans);
return 0;
}