363 網(wǎng)絡(luò)流 最小割 Dinic 算法


這種轉(zhuǎn)換是錯誤的,最大流都改變了。
```C++
//Luogu?P1344?[USACO4.4]追查壞牛奶Pollutant?Control
#include?<iostream>
#include?<cstring>
#include?<algorithm>
#include?<queue>
#define?N?10010
#define?M?200010
#define?debug?printf("%d?%s\n",__LINE__,__FUNCTION__)
typedef?long?long?ll,?i64,?LL;
const?ll?LNF?=?0x3f3f3f3f3f3f3f3f;
using?namespace?std;
const?int?mod?=?2019;
int?S,?T;
struct?edge?{
????int?v;LL?c;int?ne;
????
}?e[M];
int?h[N],?idx?=?1;?//從2,3開始配對
int?d[N],?cur[N];
int?vis[N];
void?add(int?a,?int?b,?LL?c)?{
????e[++idx]?=?{b,?c,?h[a]};
????h[a]?=?idx;
}
bool?bfs()?{?//對點(diǎn)分層,找增廣路
????memset(d,?0,?sizeof?d);
????queue<int>q;
????q.push(S);
????d[S]?=?1;
????while?(q.size())?{
????????int?u?=?q.front();
????????q.pop();
????????for?(int?i?=?h[u];?i;?i?=?e[i].ne)?{
????????????int?v?=?e[i].v;
????????????if?(d[v]?==?0?&&?e[i].c)?{
????????????????d[v]?=?d[u]?+?1;
????????????????q.push(v);
????????????????if?(v?==?T)?return?true;
????????????}
????????}
????}
????return?false;
}
LL?dfs(int?u,?LL?mf)?{?//多路增廣
????if?(u?==?T)?return?mf;
????LL?sum?=?0;
????for?(int?i?=?cur[u];?i;?i?=?e[i].ne)?{
????????cur[u]?=?i;?//當(dāng)前弧優(yōu)化
????????int?v?=?e[i].v;
????????if?(d[v]?==?d[u]?+?1?&&?e[i].c)?{
????????????LL?f?=?dfs(v,?min(mf,?e[i].c));
????????????e[i].c?-=?f;
????????????e[i?^?1].c?+=?f;?//更新殘留網(wǎng)
????????????
????????????sum?+=?f;?//累加u的流出流量
????????????mf?-=?f;?//減少u的剩余流量
????????????if?(mf?==?0)?break;?//余量優(yōu)化
????????}
????}
????if?(sum?==?0)?d[u]?=?0;?//殘枝優(yōu)化
????return?sum;
}
LL?dinic()?{?//累加可行流
????LL?flow?=?0;
????while?(bfs())?{
????????memcpy(cur,?h,?sizeof?h);
????????flow?+=?dfs(S,?LNF);
????}
????return?flow;
}
int?main()?{
????int?a[N],?b[N];
????LL?c;
????int?n,?m;
????scanf("%d%d",?&n,?&m);
????S?=?1,?T?=?n;
????for?(int?i?=?1;?i?<=?m;?i++)?{
????????scanf("%d%d%lld",?&a[i],?&b[i],?&c);
????????add(a[i],?b[i],?c*mod+1?);
????????add(b[i],?a[i],?0);
????}
????LL??res?=?dinic();
????printf("%lld?",?res/mod);
????printf("%lld\n",??res%mod);
????//最小割的最少邊數(shù)
//????idx?=?1;
//????memset(h,?0,?sizeof?h);
//????for?(int?i?=?1;?i?<=?m;?i++)?{
//????????add(a[i],?b[i],?1);
//????????add(b[i],?a[i],?0);
//????}
//????printf("%d\n",??dinic());
????return?0;
}
```
因?yàn)槌艘砸粋€數(shù)可能爆int,直接加倍LL