模板题,注意判断最大流是否为0
连接:https://www.luogu.com.cn/problem/P1343
#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;
ll edge[208][208];
int pre[208];//记录前驱结点
int vis[208];//判断是否跑过
int n,m;//结点数 边数
int s,t;//s为源点 t为汇点
ll 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())
{
ll 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) //没有增广路则直接结束,此时的flow就是最大流
{
return false;
}
ll 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()
{
int x;
scanf("%d %d %d",&n,&m,&x);
s=n;
t=1;
for(int i=1;i<=m;i++)
{
int a,b,tmp;
scanf("%d %d %d",&a,&b,&tmp);
edge[b][a]+=tmp;
}
while(change());
if(flow==0)
printf("Orz Ni Jinan Saint Cow!\n");
else
printf("%lld %lld\n",flow,x%flow==0?x/flow:x/flow+1);
return 0;
}