不说什么了,代码解释
#include<bits/stdc++.h>
#define repeat(a,b,c,g) for (int a=b,abck=(g>=0?1:-1);abck*(a)<=abck*(c);a+=g)
using namespace std;
struct edge{
int v,flow,by;//v表示指向的边,flow表示最大流流量,by是它的反向边位置
};
vector <edge> f[100010];//用vector模拟链表
queue <int> Q;//BFS神器
int level[100010];//BFS标号
int n,m;//n个点,m条边
int S,T;//S开始,T结束
int BFS()//BFS标号,return 0 表示图不同,无增广路
{
while (Q.size()) Q.pop();//清空队列
memset(level,0,sizeof(level));//必须的
Q.push(S);//放入源点
level[S]=1;//标号
while (Q.size())
{
int x = Q.front();//取出x
Q.pop();//弹点
if (x==T) return 1;//搜到T
int siz = f[x].size();//搜索所有的路径
repeat(i,0,siz-1,1)
{
if (level[f[x][i].v]==0 && f[x][i].flow)//level=0表示未搜到,f[x][i].flow表示流量
{
level[f[x][i].v]=level[x]+1;//标记下一个点
Q.push(f[x][i].v);
}
}
}
return 0;
}
int DFS(int u,int maxflow)//寻找可增广路径
{
if (u==T) return maxflow;//找到
int ret=0;
int siz = f[u].size();//搜索所有路径
repeat(i,0,siz-1,1)
{
int v = f[u][i].v;
int flow = f[u][i].flow;
if (level[u]+1==level[v] && flow > 0)//必须保证的,流量必须大于零
{
int MIN = min(maxflow-ret,flow);//找到最大流
flow = DFS(v,MIN);
f[u][i].flow -= flow;//减流量
f[f[u][i].v][f[u][i].by].flow += flow;//连反边
ret += flow;//加流量
if (ret==maxflow) return ret;//已经最大
}
}
return ret;
}
int dinic()
{
int ans=0;
while (BFS()) ans += DFS(S,100000000);//如果有可增广路径就继续找
return ans;
}
int main()
{
edge empty;//奇怪的操作
cin >> n >> m >> S >> T;
repeat(i,1,m,1)
{
int tp1,tp2,tp3;
cin >> tp1 >> tp2 >> tp3;//
f[tp1].push_back(empty);
f[tp2].push_back(empty);
int siz1 = f[tp1].size();
int siz2 = f[tp2].size();
f[tp1][siz1-1].v = tp2;// |
f[tp1][siz1-1].flow = tp3;// |
f[tp1][siz1-1].by = siz2-1;// V
f[tp2][siz2-1].v = tp1;// --->奇怪的加边
f[tp2][siz2-1].flow = 0;// ^
f[tp2][siz2-1].by = siz1-1;// |
}
cout << dinic();//愉快的输出
}