网络流入门模板题,要注意题面的坑点,两条排水沟可能有多条路径连接,需要累加
链接:https://www.luogu.com.cn/problem/P2740
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
#include <functional>
#include <vector>
#include <stack>
#include <set>
#include <bitset>
using namespace std;
typedef long long ll;
const int maxn=2e5+50;
const int inf=0x3f3f3f3f;
const int MOD=998244353;
const int HASH=131;
int edge[208][208];
int pre[208];//记录前驱结点
int vis[208];//判断是否跑过
int n,m;//结点数 边数
int s,t;//s为源点 t为汇点
int flow;//最大流
bool findpath()//bfs找增广路径
{
queue<int> q;
memset(vis,0,sizeof(vis));
memset(pre,-1,sizeof(pre));
vis[s]=1;
q.push(s);
while(!q.empty())
{
int tmp=q.front();
q.pop();
for(int i=1;i<=n;i++)
{
if(vis[i]==0&&edge[tmp][i]>0)
{
pre[i]=tmp;//记录前驱结点
vis[i]=1;
q.push(i);
if(i==t) return true;
}
}
}
return false;
}
bool change()//更新
{
if(findpath()==false) //没有增广路则直接结束
{
return false;
}
int minn=edge[pre[t]][t];//最小残差路(上一增广路的流)
for(int i=t;i!=s;i=pre[i])
{
minn=min(edge[pre[i]][i],minn);//类似前向星,反复调用找到最小残差路
}
for(int i=t;i!=s;i=pre[i])//更新残图
{
edge[pre[i]][i]-=minn;
edge[i][pre[i]]+=minn;
}
flow+=minn;
return true;
}
int main()
{
scanf("%d%d",&n,&m);
s=m;
t=1;
for(int i=1;i<=n;i++)
{
int a,b,tmp;
scanf("%d %d %d",&a,&b,&tmp);
edge[b][a]+=tmp;//坑点
}
while(change());
printf("%d\n",flow);
return 0;
}