题解 P1343 【地震逃生】
分析
我们看一下补充说明,每次只能额定的学生数量,不能出现拥挤的情况,于是它就在疯狂暗示我们这就是网络流。下面是正解。
这题肯定贪心,由于先送哪个同学没有区别,如果每次放最多的一波人出去肯定不吃亏,所以就一股脑地每次塞最多的一波人出去就行了。
所以现在是看每次最多送几个人。
然后再一看题面,这就是裸的网络流。
dinic 算法写好,算出每次最多几个人,然后除
注意,没法逃走的情况即一次一个人都出不去,特判一下就好了。
数据范围呢?出题人很贴心地给我们设置了一个
代码
#include<bits/stdc++.h>
using namespace std;
const int N=2009;
struct edge{int to,nxt,w;}e[N*2];int hd[N],tot=1;
void add(int u,int v,int w){
e[++tot]=(edge){v,hd[u],w}; hd[u]=tot;
}
int n,m,d[N],ans,x;
bool bfs(){
queue<int>q; memset(d,0,sizeof(d));
q.push(1),d[1]=1;
while(!q.empty()){
int u=q.front(); q.pop();
for(int i=hd[u],v;i;i=e[i].nxt)
if(!d[v=e[i].to]&&e[i].w){
q.push(v),d[v]=d[u]+1;
if(v==n) return 1;
}
}
return 0;
}
int dfs(int u,int flow){
if(u==n) return flow;
int rest=flow;
for(int i=hd[u],v;i&&rest;i=e[i].nxt){
if(e[i].w&&d[v=e[i].to]==d[u]+1){
int tmp=dfs(v,min(rest,e[i].w));
if(!tmp) d[v]=0;
rest-=tmp; e[i].w-=tmp; e[i^1].w+=tmp;
}
}
return flow-rest; //真正给出去的
}
int main(){
scanf("%d%d%d",&n,&m,&x);
for(int i=1,u,v,w;i<=m;i++)
scanf("%d%d%d",&u,&v,&w),add(u,v,w),add(v,u,0);
int tmp=0;
while(bfs()) while(tmp=dfs(1,1e9)) ans+=tmp;
if(!ans){puts("Orz Ni Jinan Saint Cow!");return 0;}
printf("%d ",ans);
int a2=ceil(x*1./ans);
printf("%d",a2);
return 0;
}
然后不知道什么是网络瘤的可以看:我的网络流