[最小割]luogu P1344 [USACO4.4]追查坏牛奶Pollutant Control
题面
https://www.luogu.com.cn/problem/P1344
分析
很简单的网络流,重点在于如何维护最小割边数最少。
考虑对每条边的流量在其基础上乘以一个大于总边数的值,再+1
那么新图最大流/总边数即为原图最小割,%总边数即为最小割最少边数。
代码
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; typedef long long ll; const ll Inf=3e9+10; const int N=1e3+10; struct Graph { ll c; int v,nx; }g[2*N]; int cnt=1,list[35],d[35]; int n,m,s,t; ll ans; void Add(int u,int v,ll c) {g[++cnt]=(Graph){c,v,list[u]};list[u]=cnt;} bool BFS() { queue<int> q; while (!q.empty()) q.pop(); memset(d,0,sizeof d); q.push(s);d[s]=1; while (!q.empty()) { int u=q.front();q.pop(); for (int i=list[u];i;i=g[i].nx) if (!d[g[i].v]&&g[i].c) d[g[i].v]=d[u]+1,q.push(g[i].v); } return d[t]; } ll MF(int u,ll maxf) { ll out=0,f; if (!maxf||u==t) return maxf; for (int i=list[u];i;i=g[i].nx) if (d[u]+1==d[g[i].v]) { f=MF(g[i].v,min(maxf-out,g[i].c)); out+=f; g[i].c-=f;g[i^1].c+=f; if (out==maxf) return out; } return out; } void Dinic() { while (BFS()) ans+=MF(s,Inf); } int main() { scanf("%d%d",&n,&m);s=1;t=n; for (int i=1,u,v,c;i<=m;i++) scanf("%d%d%d",&u,&v,&c),Add(u,v,1ll*c*(m+1)+1),Add(v,u,0); Dinic(); printf("%lld %lld",ans/(m+1),ans%(m+1)); }
在日渐沉没的世界里,我发现了你。