题目描述
汶川地震发生时,四川**中学正在上课,一看地震发生,老师们立刻带领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
裸的网络流,就是还卡读入优化。。。
附代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#define MAXN 210
#define MAXM 2010
#define MAX 999999999
using namespace std;
int n,m,x,c=2,s,t,head[MAXN],deep[MAXN];
struct node{
int next,to,w;
}a[MAXM<<1];
inline void add(int u,int v,int w){
a[c].to=v;a[c].w=w;
a[c].next=head[u];
head[u]=c++;
a[c].to=u;a[c].w=0;
a[c].next=head[v];
head[v]=c++;
}
bool bfs(){
int u,v;
queue<int> q;
for(int i=1;i<=n;i++)deep[i]=0;
deep[s]=1;
q.push(s);
while(!q.empty()){
u=q.front();
q.pop();
for(int i=head[u];i;i=a[i].next){
v=a[i].to;
if(a[i].w&&!deep[v]){
deep[v]=deep[u]+1;
if(v==t)return true;
q.push(v);
}
}
}
return false;
}
int dfs(int x,int limit){
if(x==t)return limit;
int v,sum,cost=0;
for(int i=head[x];i;i=a[i].next){
v=a[i].to;
if(a[i].w&&deep[v]==deep[x]+1){
sum=dfs(v,min(a[i].w,limit-cost));
if(sum>0){
a[i].w-=sum;
a[i^1].w+=sum;
cost+=sum;
if(limit==cost)break;
}
else deep[v]=-1;
}
}
return cost;
}
void dinic(){
int ans=0;
while(bfs())ans+=dfs(s,MAX);
if(ans==0){
printf("Orz Ni Jinan Saint Cow!\n");
return;
}
printf("%d ",ans);
if(x%ans==0)printf("%d\n",x/ans);
else printf("%d\n",x/ans+1);
}
int main(){
int u,v,w;
scanf("%d%d%d",&n,&m,&x);
s=1;t=n;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
dinic();
return 0;
}