在网上看了最小费用最大流的算法思路,但在看别人写的代码的时候一直不理解,就按照自己的思路,利用SPFA算法找到每条可增广的最少费用,利用dinic算法的思路来找到在最小费用的前提下能够最大增广的流量。
代码测试几组数据通过了,但未在oj上进行测试,仅是按照我所理解的思路,和我写代码的思维方式,写下了便于我理解的代码。如果有不正确的地方,请指教!
#include<bits/stdc++.h>
using namespace std;
vector<int> v[1005];
queue<int> Q;
struct node
{
int c,f;
}edges[1005][1005];//网络流建图
int n,m,source,endi;
int Map[1005][1005];//花费图
int dis[1005];
bool vis[1005];
int level[1005];
int costflow;
bool SPFA()
{
memset(vis,false,sizeof(vis));
memset(dis,0x3f3f3f,sizeof(dis));
memset(level,-1,sizeof(level));
dis[source]=0;
Q.push(source);
int u;
vis[source]=true;
level[source]=1;
while(!Q.empty())
{
u=Q.front();
Q.pop();
vis[u]=false;
for(int i=0;i<v[u].size();i++)
{
int e=v[u][i];
if(level[e]==-1&&dis[e]>dis[u]+Map[u][e]&&edges[u][e].f<edges[u][e].c)
{
dis[e]=dis[u]+Map[u][e];
level[e]=level[u]+1;
if(vis[e]==false)
{
Q.push(e);
vis[e]=true;
}
}
}
}
if(level[endi]==-1)
return false;
return true;
}
int dinic_dfs(int u, int cp) { //use dfs to augment the flow
int tmp = cp;
int v, t;
if (u == endi)
return cp;
for (v = 1; v <= endi&&tmp; v++)
{
if (level[u] + 1 == level[v])
{
if (edges[u][v].c>edges[u][v].f)
{
t = dinic_dfs(v, min(tmp, edges[u][v].c - edges[u][v].f));
edges[u][v].f += t;
edges[v][u].f -= t;
costflow+=t*Map[u][v];
tmp -= t;
}
}
}
return cp - tmp;
}
int MCMF()
{
costflow=0;
int sum=0;
while(SPFA())
{
while (dinic_dfs(1, 0x3f3f3f))
{
//sum += tf;
}
}
cout<<costflow<<endl;
}
int main()
{
while(~scanf("%d%d",&n,&m)&&(n||m))
{
source=1;
endi=n;
int s,t,value,cost;
memset(Map,0x3f3f3f,sizeof(Map));
memset(edges,0,sizeof(edges));
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%d",&s,&t,&cost,&value);
v[s].push_back(t);
v[t].push_back(s);
Map[s][t]=value;
Map[t][s]=value;
edges[s][t].c=cost;
}
MCMF();
}
return 0;
}