网络流模板
陈年模板,不如看这里。
最大流
dinic
int head[MAXN],tot = 1;
struct edge
{
int v,nxt;LL w;
}e[MAXM << 1];
void Add_Edge(int x,int y,LL z)
{
e[++tot].v = y;
e[tot].w = z;
e[tot].nxt = head[x];
head[x] = tot;
}
int d[MAXN];
bool bfs(int s,int t)
{
for(int i = 1;i <= n;++ i) d[i] = -1;
d[s] = 0;
queue<int> q; q.push(s);
while(!q.empty())
{
int p = q.front(); q.pop();
for(int i = head[p]; i ;i = e[i].nxt)
if(d[e[i].v] == -1 && e[i].w > 0)
{
d[e[i].v] = d[p] + 1;
q.push(e[i].v);
}
}
return d[t] != -1;
}
int cur[MAXN];
LL dfs(int x,LL flow,int t)
{
if(x == t) return flow;
LL ret = 0;
for(int &i = cur[x]; i ;i = e[i].nxt)
{
if(d[x] + 1 == d[e[i].v] && e[i].w > 0)
{
LL dz = dfs(e[i].v,Min(flow-ret,e[i].w),t);//记得是flow-ret而不是flow!!!(货物变多可还行
e[i].w -= dz; e[i^1].w += dz;
if((ret += dz) == flow) break;
}
}
if(!ret) d[x] = -1;
return ret;
}
LL dinic(int s,int t)
{
LL ret = 0;
while(bfs(s,t))
{
for(int i = 1;i <= n;++ i) cur[i] = head[i];
ret += dfs(s,INF,t);
}
return ret;
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
n = Read(); m = Read(); s = Read(); t = Read();
for(int i = 1,u,v,w;i <= m;++ i)
{
u = Read(),v = Read(),w = Read();
Add_Edge(u,v,w);
Add_Edge(v,u,0);
}
Put(dinic(s,t));
return 0;
}
最小费用最大流
单路
int head[MAXN],tot = 1;//tot初值一定要是1啊啊啊啊啊啊啊啊啊
struct edge
{
int v,w,c,nxt;
}e[MAXM << 1];
void Add_Edge(int u,int v,int w,int c)
{
e[++tot].v = v;
e[tot].w = w;
e[tot].c = c;
e[tot].nxt = head[u];
head[u] = tot;
}
int pre[2][MAXN],dis[MAXN],flow[MAXN],maxflow,maxcost;
bool vis[MAXN];
bool bfs(int s,int t)
{
for(int i = 1;i <= n;++ i) dis[i] = INF;
queue<int> q; q.push(s);
flow[s] = INF; dis[s] = 0;
while(!q.empty())
{
int p = q.front(); q.pop();
vis[p]= 0;
for(int i = head[p]; i ;i = e[i].nxt)
{
if(dis[p] + e[i].c < dis[e[i].v] && e[i].w > 0)
{
dis[e[i].v] = dis[p] + e[i].c;
pre[0][e[i].v] = p;
pre[1][e[i].v] = i;
flow[e[i].v] = Min(flow[p],e[i].w);
if(!vis[e[i].v])
{
vis[e[i].v] = 1;
q.push(e[i].v);
}
}
}
}
return dis[t] != INF;
}
void MCMF(int s,int t)
{
while(bfs(s,t))
{
maxflow += flow[t];
maxcost += flow[t] * dis[t];
for(int now = t;now != s;now = pre[0][now])
{
e[pre[1][now]].w -= flow[t];
e[pre[1][now]^1].w += flow[t];
}
}
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
n = Read(); m = Read(); s = Read(); t = Read();
for(int i = 1,u,v,w,c;i <= m;++ i)
{
u = Read(); v = Read(); w = Read(); c = Read();
Add_Edge(u,v,w,c);
Add_Edge(v,u,0,-c);
}
MCMF(s,t);
Put(maxflow,' '),Put(maxcost);
return 0;
}
多路(听说叫zkw)
//12252024832524
#include <bits/stdc++.h>
#define TT template<typename T>
using namespace std;
typedef long long LL;
const int MAXN = 5005;
const int MAXM = 50005;
const int INF = 2147483647;
int n,m,S,T;
LL Read()
{
LL x = 0,f = 1;char c = getchar();
while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();}
while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
return x * f;
}
TT void Put1(T x)
{
if(x > 9) Put1(x/10);
putchar(x%10^48);
}
TT void Put(T x,char c = -1)
{
if(x < 0) putchar('-'),x = -x;
Put1(x); if(c >= 0) putchar(c);
}
TT T Max(T x,T y){return x > y ? x : y;}
TT T Min(T x,T y){return x < y ? x : y;}
TT T Abs(T x){return x < 0 ? -x : x;}
int head[MAXN],tot = 1;
struct edge{
int v,w,c,nxt;
}e[MAXM<<1];
void Add_Edge(int u,int v,int w,int c){
e[++tot] = edge{v,w,c,head[u]};
head[u] = tot;
}
void Add_Double_Edge(int u,int v,int w,int c){
Add_Edge(u,v,w,c);
Add_Edge(v,u,0,-c);
}
int dis[MAXN],cur[MAXN],maxflow,mincost;
bool inq[MAXN],vis[MAXN];
bool bfs(int S,int T){
for(int i = 1;i <= n;++ i) dis[i] = INF;
queue<int> q; q.push(S); dis[S] = 0;
while(!q.empty()){
int x = q.front(); q.pop(); inq[x] = 0;
for(int i = head[x],v; i ;i = e[i].nxt)
if(e[i].w && dis[x] + e[i].c < dis[v = e[i].v]){
dis[v] = dis[x] + e[i].c;
if(!inq[v]) inq[v] = 1,q.push(v);
}
}
return dis[T] < INF;
}
int dfs(int x,int flow,int T) {
if(x == T) return flow;
int ret = 0; vis[x] = 1;
for(int &i = cur[x],v; i ;i = e[i].nxt)
if(e[i].w && dis[x] + e[i].c == dis[v = e[i].v] && !vis[v]){
int dz = dfs(v,Min(flow-ret,e[i].w),T);
e[i].w -= dz; e[i^1].w += dz;
if((ret += dz) == flow) break;
}
vis[x] = 0;
return ret;
}
void MCMF(int S,int T){
while(bfs(S,T)){
for(int i = 1;i <= n;++ i) cur[i] = head[i];
int ret = dfs(S,INF,T);
maxflow += ret,mincost += ret * dis[T];
}
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
n = Read(); m = Read(); S = Read(); T = Read();
for(int i = 1,u,v,w;i <= m;++ i){
u = Read(),v = Read(),w = Read();
Add_Double_Edge(u,v,w,Read());
}
MCMF(S,T);
Put(maxflow,' '),Put(mincost,'\n');
return 0;
}