问题:最小费用最大流
思路:求最小费用最大流与求最大流的不同是最小费用最大流的模型的边上多了一个量cost,所以边上的表示为(flowi,costi),从S到T的最小费用最大流,每次从S到T找一条cost最小的路另加条件是flow不为0,则累加mincost+=minflow*costi,就这样循环知道找不到这样的最短路为止!该题需注意的是:加一个S点到1的flow为2,cost为0,,反向为flow为0,cost为0;加一个T点,n到T的flow为2,cost为0,反向为flow为0,cost为0;当输入数据内有边a-b的,则要添加两次边,每次都是添加正反边即添加a->b和b->a!哎,现在这个算法还不是太懂,只知道实现;算了,再做题研究研究吧!
#include <stdio.h>
#include <memory.h>
#define N 1002
#define M 400002
#define MAXVAL 1000000000
#define MOV(x) (x=(x+1)%N)
int nodevp[N];
int nodeu[M],flow[M],cost[M],next[M],ind;
int n,m,s,t;
void addedge(int v,int u,int fw,int te)
{
nodeu[ind]=u;
flow[ind]=fw;
cost[ind]=te;
next[ind]=nodevp[v];
nodevp[v]=ind++;
}
void getDataAndBuildGraph()
{
int i,v,u,val;
scanf("%d %d",&n,&m); s=0; t=n+1;
memset(nodevp,-1,sizeof(nodevp)); ind=0;
for(i=0;i<m;i++)
{
scanf("%d %d %d",&v,&u,&val);
addedge(v,u,1,val);
addedge(u,v,0,-val);
addedge(u,v,1,val);
addedge(v,u,0,-val);
}
addedge(s,1,2,0);
addedge(1,s,0,0);
addedge(n,t,2,0);
addedge(t,n,0,0);
}
int dist[N],pre[N];
int queue[N],inqueue[N],font,rear;
int SPFA()
{
int i,v,u;
for(i=0;i<=t;i++) dist[i]=MAXVAL; dist[s]=0;
memset(pre,-1,sizeof(pre));
memset(inqueue,0,sizeof(inqueue));
font=rear=0; queue[MOV(rear)]=s; inqueue[s]=1;
while(font!=rear)
{
v=queue[MOV(font)]; inqueue[v]=0;
for(i=nodevp[v];~i;i=next[i])
{
u=nodeu[i];
if(flow[i] && dist[u]>dist[v]+cost[i])
{
dist[u]=dist[v]+cost[i]; pre[u]=i;
if(!inqueue[u]) queue[MOV(rear)]=u,inqueue[u]=1;
}
}
}
if(dist[t]!=MAXVAL) return 1;
else return 0;
}
int mincost_maxflow()
{
int i,ans=0;
while(SPFA())
{
ans+=dist[t];
for(i=pre[t];~i;i=pre[nodeu[i^1]])
{
flow[i]--;
flow[i^1]++;
}
}
return ans;
}
void solve()
{
getDataAndBuildGraph();
printf("%d\n",mincost_maxflow());
}
int main()
{
// freopen("input.txt","r",stdin);
solve();
return 0;
}