网络流模板
内容均来自以下两个blog
EK与dinic
ISAP与HLPP
最大流
最普通的版本(dinic)
#include<bits/stdc++.h>
using namespace std;
#define maxm 200005
#define maxn 10010
#define inf 0x3f3f3f3f
struct Edge
{
int fr,to,val;
}eg[maxm];
int edgenum=1,maxflow,n,m,head[maxn];
inline void add(int fr,int to,int val)
{
eg[++edgenum].fr=head[fr];
eg[edgenum].to=to;
eg[edgenum].val=val;
head[fr]=edgenum;
}
int deep[maxn],vis[maxn],s,t;
bool bfs()
{
memset(deep,0x3f,sizeof(deep));
memset(vis,0,sizeof(vis));
deep[s]=0;
queue<int> q;
q.push(s);
while(!q.empty())
{
int tmp=q.front();
q.pop();
vis[tmp]=0;
for(int i=head[tmp];i;i=eg[i].fr)
{
int to=eg[i].to;
if(deep[to]>deep[tmp]+1&&eg[i].val)
{
deep[to]=deep[tmp]+1;
if(!vis[to])
vis[to]=1,q.push(to);
}
}
}
if(deep[t]!=inf) return 1;
return 0;
}
inline int dfs(int now,int flow)
{
if(now==t) return flow;
int tmpflow=0;
for(int i=head[now];i;i=eg[i].fr)
{
int to=eg[i].to;
if(deep[to]==deep[now]+1&&eg[i].val)
{
if(tmpflow=dfs(to,min(flow,eg[i].val)))
{
eg[i].val-=tmpflow;
eg[i^1].val+=tmpflow;
return tmpflow;
}
}
}
return 0;
}
void dinic()
{
int lowflow;
while(bfs())
while(lowflow=dfs(s,inf)) maxflow+=lowflow;
}
int main()
{
scanf("%d%d%d%d",&n,&m,&s,&t);
int u,v,w;
for(int i=1;i<=m;++i)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,0);
}
dinic();
printf("%d\n",maxflow);
return 0;
}
加上多路增广和当前弧
#include<bits/stdc++.h>
using namespace std;
#define maxm 200005
#define maxn 10010
#define inf 0x3f3f3f3f
struct Edge
{
int fr,to,val;
}eg[maxm];
int edgenum=1,maxflow,n,m,head[maxn],cur[maxn];
inline void add(int fr,int to,int val)
{
eg[++edgenum].fr=head[fr];
eg[edgenum].to=to;
eg[edgenum].val=val;
head[fr]=edgenum;
}
int deep[maxn],vis[maxn],s,t;
bool bfs()
{
for(register int i=0;i<=n;++i) deep[i]=inf,vis[i]=0,cur[i]=head[i];
deep[s]=0;
queue<int> q;
q.push(s);
while(!q.empty())
{
int tmp=q.front();
q.pop();
vis[tmp]=0;
for(int i=head[tmp];i;i=eg[i].fr)
{
int to=eg[i].to;
if(deep[to]>deep[tmp]+1&&eg[i].val)
{
deep[to]=deep[tmp]+1;
if(!vis[to])
vis[to]=1,q.push(to);
}
}
}
if(deep[t]!=inf) return 1;
return 0;
}
inline int dfs(int now,int flow)
{
if(now==t)
{
maxflow+=flow;
return flow;
}
int tmpflow=0,used=0;
for(int i=cur[now];i;i=eg[i].fr)
{
int to=eg[i].to;
cur[now]=i;
if(deep[to]==deep[now]+1&&eg[i].val)
{
if(tmpflow=dfs(to,min(flow-used,eg[i].val)))
{
used+=tmpflow;
eg[i].val-=tmpflow;
eg[i^1].val+=tmpflow;
if(used==flow) break;
}
}
}
return used;
}
inline void dinic()
{
while(bfs()) dfs(s,inf);
}
int main()
{
scanf("%d%d%d%d",&n,&m,&s,&t);
int u,v,w;
for(int i=1;i<=m;++i)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,0);
}
dinic();
printf("%d\n",maxflow);
return 0;
}
ISAP(当前弧)话说为什么不能跑费用流啊
#include<bits/stdc++.h>
using namespace std;
#define maxm 200005
#define maxn 10010
#define inf 0x3f3f3f3f
struct Edge
{
int fr,to,val;
}eg[maxm];
int edgenum=1,maxflow,n,m,head[maxn],cur[maxn],gap[maxn];
inline void add(int fr,int to,int val)
{
eg[++edgenum]=(Edge){head[fr],to,val};
head[fr]=edgenum;
}
int deep[maxn],s,t;
void bfs()
{
for(register int i=0;i<=n;++i) deep[i]=-1,gap[i]=0;
deep[t]=0;
gap[0]=1;
queue<int> q;
q.push(t);
while(!q.empty())
{
int tmp=q.front();
q.pop();
for(int i=head[tmp];i;i=eg[i].fr)
{
int to=eg[i].to;
if(deep[to]==-1)
{
q.push(to);
deep[to]=deep[tmp]+1;
++gap[deep[to]];
}
}
}
}
inline int dfs(int now,int flow)
{
if(now==t)
{
maxflow+=flow;
return flow;
}
int tmpflow=0,used=0;
for(int i=cur[now];i;i=eg[i].fr)
{
int to=eg[i].to;
cur[now]=i;
if(deep[to]+1==deep[now]&&eg[i].val)
{
if(tmpflow=dfs(to,min(flow-used,eg[i].val)))
{
used+=tmpflow;
eg[i].val-=tmpflow;
eg[i xor 1].val+=tmpflow;
}
if(used==flow) return used;
}
}
if(!--gap[deep[now]]) deep[s]=n+1;
++gap[++deep[now]];
return used;
}
inline void ISAP()
{
bfs();
while(deep[s]<n)
{
memcpy(cur,head,sizeof(head));
dfs(s,inf);
}
}
int main()
{
scanf("%d%d%d%d",&n,&m,&s,&t);
int u,v,w;
for(int i=1;i<=m;++i)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,0);
}
ISAP();
printf("%d\n",maxflow);
return 0;
}
HLPP先咕了
最小费用最大流
dinic+spfa
#include<bits/stdc++.h>
using namespace std;
#define maxm 100005
#define maxn 5010
#define inf 0x3f3f3f3f
struct Edge
{
int fr,to,val,wei;
}eg[maxm];
int edgenum=1,maxflow,mincost,n,m,head[maxn],cur[maxn];
inline void add(int fr,int to,int val,int wei)
{
eg[++edgenum]=(Edge){head[fr],to,val,wei};
head[fr]=edgenum;
}
int dis[maxn],vis[maxn],s,t;
bool bfs()
{
for(register int i=0;i<=n;++i) dis[i]=inf,vis[i]=0,cur[i]=head[i];
dis[s]=0;
queue<int> q;
q.push(s);
while(!q.empty())
{
int tmp=q.front();
q.pop();
vis[tmp]=0;
for(int i=head[tmp];i;i=eg[i].fr)
{
int to=eg[i].to;
if(dis[to]>dis[tmp]+eg[i].wei&&eg[i].val)
{
dis[to]=dis[tmp]+eg[i].wei;
if(!vis[to])
vis[to]=1,q.push(to);
}
}
}
if(dis[t]!=inf) return 1;
return 0;
}
inline int dfs(int now,int flow)
{
if(now==t)
{
vis[t]=1;
maxflow+=flow;
return flow;
}
vis[now]=1;
int tmpflow=0,used=0;
for(int i=cur[now];i;i=eg[i].fr)
{
int to=eg[i].to;
cur[now]=i;
if((!vis[to]||to==t)&&dis[to]==dis[now]+eg[i].wei&&eg[i].val)
{
if(tmpflow=dfs(to,min(flow-used,eg[i].val)))
{
used+=tmpflow;
mincost+=eg[i].wei*tmpflow;
eg[i].val-=tmpflow;
eg[i^1].val+=tmpflow;
if(used==flow) break;
}
}
}
return used;
}
inline void dinic()
{
while(bfs()) dfs(s,inf);
}
int main()
{
scanf("%d%d%d%d",&n,&m,&s,&t);
int u,v,w,h;
for(int i=1;i<=m;++i)
{
scanf("%d%d%d%d",&u,&v,&w,&h);
add(u,v,w,h);
add(v,u,0,-h);
}
dinic();
printf("%d %d\n",maxflow,mincost);
return 0;
}
一切伟大的行动和思想,都有一个微不足道的开始。
There is a negligible beginning in all great action and thought.
There is a negligible beginning in all great action and thought.