P1343 地震逃生
模板网络流最大流
题目链接:https://www.luogu.com.cn/problem/P1343
源点为1,终点为n
#include <bits/stdc++.h> using namespace std; const int maxn=200000+5; int last[maxn],nxt[maxn*2],to[maxn*2],wi[maxn*2],cnt=-1; int deep[maxn]; int s,t,n,m,x; void add(int u,int v,int w) { to[++cnt]=v; wi[cnt]=w; nxt[cnt]=last[u]; last[u]=cnt; return ; } bool bfs() { queue < int > Q; memset(deep,0,sizeof(deep)); while(!Q.empty()) Q.pop();//预处理,清空队列,deep Q.push(s); deep[s]=1;//加入源头 do{ int u=Q.front(); Q.pop(); for(int i=last[u];i!=-1;i=nxt[i]) if(wi[i]>0 && deep[to[i]]==0)//边有残量 点未被占领 { deep[to[i]]=deep[u]+1; Q.push(to[i]); } }while(!Q.empty()); if(deep[t]==0) return 0;//未经过t点 返回false return 1; } int dfs(int u,int dist) { if(u==t) return dist;//到达终点 for(int i=last[u];i!=-1;i=nxt[i]) if(deep[to[i]]==deep[u]+1 && wi[i]!=0)//分层正确 与 有剩余残量 { int di=dfs(to[i],min(dist,wi[i])); if(di>0) { wi[i]-=di;//正向边减 wi[i^1]+=di;//反向边加 return di; } } return 0; } int dinic() { int ans=0; while(bfs()) while(int d=dfs(s,10000007)) ans+=d; return ans; } int main() { memset(last,-1,sizeof(last)); memset(nxt,-1,sizeof(nxt)); cin>>n>>m>>x; s=1; t=n; for(int i=1;i<=m;i++) { int u,v,w; cin>>u>>v>>w; add(u,v,w); add(v,u,0); } int d=dinic(); if(d==0) { cout<<"Orz Ni Jinan Saint Cow!"; return 0; } cout<<d<<" "; if(x%d==0) cout<<x/d; else cout<<x/d+1; return 0; }