1. 程式人生 > 實用技巧 >[最小割]luogu P1344 [USACO4.4]追查壞牛奶Pollutant Control

[最小割]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)); }
View Code