终于快把网络流的模板写完了,先贴几个,存边用前向星实现,既保证了速度又免去了写链表的麻烦,代码绝对是你能找到的代码中最精简的
//EK
#include
#include
using namespace std;
#include
#define MAXN 300
#define MAXFLOW 2000000000
int n,s,t,m,flow[MAXN+1][MAXN+1],map[MAXN+1][MAXN+1],pre[MAXN+1];
void init()
{
int i,a,b,c;
memset(map,0,sizeof(map));
memset(flow,0,sizeof(flow));
memset(pre,0,sizeof(pre));
cin>>n>>s>>t>>m;
for(i=1;i<=m;i++)
{
cin>>a>>b>>c;
map[a][0]++;
map[a][map[a][0]]=b;
map[b][0]++;
map[b][map[b][0]]=a;
flow[a][b]+=c;//对于重边的存在,推荐用+=
}
}
int bfs()
{
int i,tt[MAXN+1],start,finish,chk[MAXN+1],k;
memset(tt,0,sizeof(tt));
memset(chk,0,sizeof(chk));
start=1;finish=1;tt[1]=s;
while(start<=finish)
{
for(i=1;i<=map[tt[start]][0];i++)
if ((!chk[map[tt[start]][i]])&&(flow[tt[start]][map[tt[start]][i]]))
{
k=map[tt[start]][i];
finish++;
tt[finish]=k;
chk[k]=1;
pre[k]=tt[start];
if(k==t) return 1;
}
start++;
}
return 0;
}
int min(int a,int b)
{
if (a else return b;
}
int main()
{
int ans,k,v;
init();
ans=0;
while (bfs())
{
k=t;v=MAXFLOW;
while(k!=s)
{
v=min(v,flow[pre[k]][k]);
k=pre[k];
}
k=t;ans+=v;
while(k!=s)
{
flow[pre[k]][k]-=v;
flow[k][pre[k]]+=v;
k=pre[k];
}
}
cout<
//最大流 Dinic 比EK多写了个函数 用来计算源点到这个点经过的最少边数 加了个判断条件
#include
#include
using namespace std;
#include
#define MAXN 300
#define MAXFLOW 2000000000
int n,s,t,m,flow[MAXN+1][MAXN+1],map[MAXN+1][MAXN+1],pre[MAXN+1],d[MAXN+1];
void init()
{
int i,a,b,c;
memset(map,0,sizeof(map));
memset(flow,0,sizeof(flow));
memset(pre,0,sizeof(pre));
for(i=1;i<=m;i++)
{
cin>>a>>b>>c;
map[a][0]++;
map[a][map[a][0]]=b;
map[b][0]++;
map[b][map[b][0]]=a;
flow[a][b]+=c;
}
}
void Re_d()
{
int i,j,a[300],start,final,cur;
memset(d,0,sizeof(d));
start=1;final=1;
d[s]=1;
a[1]=s;
while(start<=final)
{
cur=a[start++];
for(i=1;i<=map[cur][0];i++)
{
j=map[cur][i];
if ( (flow[cur][j]>0)
&& (!d[j]) )
{
d[j]=d[cur]+1;
a[++final]=j;
}
}
}
}
int bfs()
{
int i,tt[MAXN+1],start,finish,chk[MAXN+1],k;
memset(tt,0,sizeof(tt));
memset(chk,0,sizeof(chk));
start=1;finish=1;tt[1]=s;
while(start<=finish)
{
for(i=1;i<=map[tt[start]][0];i++)
if ((!chk[map[tt[start]][i]])&&(flow[tt[start]][map[tt[start]][i]])&&(d[tt[start]]+1==d[map[tt[start]][i]]))
//(d[tt[start]+1==d[map[tt[start]][i]])加这个条件
{
k=map[tt[start]][i];
finish++;
tt[finish]=k;
chk[k]=1;
pre[k]=tt[start];
if(k==t) return 1;
}
start++;
}
return 0;
}
int min(int a,int b)
{
if (a else return b;
}
int main()
{
int ans,k,v;
while(cin>>m>>n)
{
s=1;t=n;
//cin>>s>>t;//s,t是源点和汇点
init();
ans=0;
Re_d();
while (bfs())
{
k=t;v=MAXFLOW;
while(k!=s)
{
v=min(v,flow[pre[k]][k]);
k=pre[k];
}
k=t;ans+=v;
while(k!=s)
{
flow[pre[k]][k]-=v;
flow[k][pre[k]]+=v;
k=pre[k];
}
Re_d();
}
cout<
}
//最小费用最大流 (Dijkstra实现)
#include
#include
#include
using namespace std;
#define MAXN 300
#define MAXFlow 2000000
#define MAXV 200000000
int n,s,t,m,k,Flow[MAXN+1][MAXN+1],map[MAXN+1][2*MAXN+1],pre[MAXN+1],d[MAXN+1],Fee[MAXN+1][MAXN+1],d0[MAXN+1];
//Flow流量,Fee价值,map用记录儿子的形式存边,pre[i]i的前继
bool init()
{
int i,a,b,j,fee,u,v,l,c;
memset(map,0,sizeof(map));
memset(Flow,0,sizeof(Flow));
memset(pre,0,sizeof(pre));
for(i=0;i<=MAXN;i++)
d[i]=MAXV;
for(i=0;i<=MAXN;i++)
for(j=0;j<=MAXN;j++)
{
Fee[i][j]=MAXV;
}
cin>>n>>m>>s>>t;
if ((n==0)&&(m==0)&&(k==0)) return false;
for(i=1;i<=m;i++)
{
cin>>a>>b>>c>>fee;
map[a][0]++;
map[a][map[a][0]]=b;
map[b][0]++;
map[b][map[b][0]]=a;
Flow[a][b]=c;
Fee[a][b]=fee;
Fee[b][a]=-fee;
}
d[s]=0;
return true;
}
int dijkstra()
{
int i,tt[MAXN+1],chk[MAXN+1],k,min_d,j,min_i,ft;
memset(tt,0,sizeof(tt));
memset(chk,0,sizeof(chk));
for(i=0;i<=MAXN;i++)
d[i]=MAXV;
d[s]=0;
ft=0;
min_i=MAXV;
for(j=1;j<=n;j++)
{
min_d=MAXV;
for(i=1;i<=n;i++)
if ((!chk[i])&&(d[i]
min_i=i;
min_d=d[i];
}
if (min_d==MAXV) break;
chk[min_i]=1;
for(i=1;i<=map[min_i][0];i++)
if (Flow[min_i][map[min_i][i]]>0)
{
k=map[min_i][i];
if (d[k]>(d[min_i]+Fee[min_i][k]-d0[min_i]+d0[k]))
{
d[k]=d[min_i]+Fee[min_i][k]-d0[min_i]+d0[k];
pre[k]=min_i;
}
}
}
return (d[t]!=MAXV);
}
void re_D()
{
int i;
for(i=0;i<=n;i++) d0[i]=-d[i];
}
int min(int a,int b)
{
if (a else return b;
}
int main()
{
int ans,k,v,st;
while(init())
{
ans=0;
memset(d0,0,sizeof(d0));
while (dijkstra())
{
k=t;v=MAXFlow;
while(k!=s)
{
v=min(v,Flow[pre[k]][k]);
k=pre[k];
}
k=t;ans+=v*(d[t]-d0[t]);
while(k!=s)
{
Flow[pre[k]][k]-=v;
Flow[k][pre[k]]+=v;
k=pre[k];
}
re_D();
}
cout<
return 0;
}