改日再详写算法
例题:点击这里
#include <cstdio>
#include <cstring>//建议使用ISAP算法
#include <vector>
#include<queue>
#include<iostream>
#include <algorithm>
#define maxd 10000+5
#define maxm 100000+5
const int inf=0x7ffffff;
using namespace std;
int n,m,s,t;
struct Edge{
int to;
int w;
int next;
} edge[210000];
int head[maxd];
int cur[maxd];
int dep[maxd];
int edge_num=-1;
void addEdge2(int from, int to, int dis){
edge[++edge_num].to = to;
edge[edge_num].w = dis;
edge[edge_num].next = head[from];
head[from] = edge_num;
}
void addEdge(int from, int to, int dis){
addEdge2(from, to, dis), addEdge2(to, from, 0);
}
int dfs(int u,int flow){//dfs求増广路 ,u是当前节点,flow是当前流量
if(u==t) return flow;//到达汇点,返回
int flowsum=0,flowmin;
for(int& i=cur[u];i!=-1;i=edge[i].next){//遍历与u 相连的所有节点
int v=edge[i].to;
if(dep[v]==dep[u]+1&&edge[i].w>0){//满足层次且流量大于0
flowmin=dfs(v,min(flow,edge[i].w));//flowmin表示该増广路中拥有最小流量的边的流量
flow-=flowmin;//当前流量
edge[i].w-=flowmin;//每条边的权都减去该增广路中拥有最小流量的边的流量
flowsum+=flowmin;//要求的总流量
edge[i^1].w+=flowmin;//将每条边的反向边的权增加这个值
if(!flow) break;
}
}
if (!flowsum) dep[u] = -1;
return flowsum;
}
bool bfs(){//dinic算法用bfs分层
memset(dep,-1,sizeof(dep));
queue<int>q;
q.push(s);
dep[s]=0;
int u,v;
while(!q.empty()){
u=q.front();
q.pop();
for(int i=head[u];i!=-1;i=edge[i].next){
v=edge[i].to;
if(dep[v]==-1&&edge[i].w>0){
dep[v]=dep[u]+1;
q.push(v);
}
}
}
return (dep[t]!=-1);
}
int dinic(){
int max_flow = 0;
while (bfs()){
for (int i = 1; i <= n; ++i) cur[i] = head[i];
max_flow += dfs(s, inf);
}
return max_flow;
}
int main() {
scanf("%d%d%d%d",&n,&m,&s,&t);
memset(head,-1,sizeof(head));
for(int i=0;i<m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addEdge(u,v,w);
}
printf("%d",dinic());
return 0;
}