版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40924940/article/details/84281981
题目描述
汶川地震发生时,四川**中学正在上课,一看地震发生,老师们立刻带领x名学生逃跑,整个学校可以抽象地看成一个有向图,图中有n个点,m条边。1号点为教室,n号点为安全地带,每条边都只能容纳一定量的学生,超过楼就要倒塌,由于人数太多,校长决定让同学们分成几批逃生,只有第一批学生全部逃生完毕后,第二批学生才能从1号点出发逃生,现在请你帮校长算算,每批最多能运出多少个学生,x名学生分几批才能运完。
输入输出格式
输入格式:
第一行3个整数n,m,x(x<2^31,n<=200,m<=2000);以下m行,每行三个整数a,b,c(a1,a<>b,0描述一条边,分别代表从a点到b点有一条边,且可容纳c名学生。
输出格式:
两个整数,分别表示每批最多能运出多少个学生,x名学生分几批才能运完。如果无法到达目的地(n号点)则输出“Orz Ni Jinan Saint Cow!”
输入输出样例
输入样例#1: 复制
6 7 7 1 2 1 1 4 2 2 3 1 4 5 1 4 3 1 3 6 2 5 6 1
输出样例#1: 复制
3 3
摸板题了。。。继续练习最大流手法。。。
不过只需要最后在除以下就好了。。。。
以下为AC 代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 500;
const int INF = 0x3f3f3f3f;
#define ll long long int
ll n,m,k;
ll pre[maxn];
ll ed[maxn][maxn];
ll flow[maxn];
ll min(ll a, ll b)
{
if(a<b)
return a;
else
return b;
}
bool bfs(int st, int en)
{
bool vis[maxn];
queue<int> q;
memset(vis,false,sizeof(vis));
memset(pre,-1,sizeof(pre));
q.push(st);
vis[st]=true;
while(q.size())
{
int e=q.front();
q.pop();
if(e==en)
return true;
for(int i=1; i<=n; i++)
{
if(!vis[i]&&ed[e][i])
{
pre[i]=e;
vis[i]=true;
q.push(i);
}
}
}
return false;
}
ll dfs(int st, int en)
{
ll u,flow=0,mx;
while(bfs(st, en))
{
u=en,mx=INF;
while(pre[u]!=-1)
{
mx = min(mx, ed[pre[u]][u]);
u = pre[u];
}
flow += mx;
u = en;
while(pre[u]!=-1)
{
ed[pre[u]][u] -= mx;
ed[u][pre[u]] += mx;
u = pre[u];
}
}
return flow;
}
int main()
{
scanf("%lld%lld%lld",&n,&m,&k);
ll x,y,z;
memset(ed,0,sizeof(ed));
for(int i=1;i<=m;i++)
{
scanf("%lld%lld%lld",&x,&y,&z);
ed[x][y]+=z;
}
ll temp = dfs(1,n);
if(temp == 0)
{
printf("Orz Ni Jinan Saint Cow!\n");
}
else if(k%temp == 0)
{
printf("%lld %lld\n",temp ,k/temp);
}
else
{
printf("%lld %lld\n",temp ,k/temp + 1);
}
return 0;
}