洛谷1343地震逃生
阿新 • • 發佈:2017-12-01
space ref bsp 如果 return ble cap sca 題目
很裸的題目啊,直接建圖maxflow再除一除。
題目戳這裏
題目描述
汶川地震發生時,四川**中學正在上課,一看地震發生,老師們立刻帶領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
說明
【註釋】
比如有圖
1 2 100
2 3 1
100個學生先沖到2號點,然後1個1個慢慢沿2-3邊走過去
18神牛規定這樣是不可以的……
也就是說,每批學生必須同時從起點出發,並且同時到達終點
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<queue> #define ll long long #define N 205 using namespace std; int n,m,x,tot,hd[N],cur[N],vis[N],d[N]; struct edge{int v,next,flow,cap;}e[N*20]; void adde(int u,int v,int c){ e[tot].v=v; e[tot].cap=c; e[tot].next=hd[u]; hd[u]=tot++; } bool bfs(){ queue<int>q; memset(vis,0,sizeof(vis)); q.push(1);d[1]=0;vis[1]=1; while(!q.empty()){ int u=q.front();q.pop(); for(int i=hd[u];~i;i=e[i].next){ int v=e[i].v; if(e[i].cap-e[i].flow<=0||vis[v])continue; d[v]=d[u]+1;vis[v]=1; q.push(v); } } return vis[n]; } int dfs(int u,int a){ if(!a||u==n)return a; int flow=0,f; for(int &i=cur[u];~i;i=e[i].next){ int v=e[i].v; if(d[u]+1==d[v]&&(f=dfs(v,min(e[i].cap-e[i].flow,a)))){ e[i].flow+=f; e[i^1].flow-=f; flow+=f;a-=f; if(!a)break; } } return flow; } int main(){ //freopen(".in","r",stdin); //freopen(".out","w",stdout); memset(hd,-1,sizeof(hd)); scanf("%d%d%d",&n,&m,&x); for(int i=1;i<=m;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); adde(a,b,c);adde(b,a,0); } int a1=0,a2=0; while(bfs()){ for(int i=1;i<=n;i++)cur[i]=hd[i]; a1+=dfs(1,2147483647); } if(!a1){ printf("Orz Ni Jinan Saint Cow!"); return 0; } if(x%a1)a2=x/a1+1; else a2=x/a1; printf("%d %d",a1,a2); return 0; }
洛谷1343地震逃生