用SPFA的最小费用流算法

来源:互联网 发布:sql 事务回滚 编辑:程序博客网 时间:2024/05/16 09:25

作法就是每次找到一条合计费用最小的从起点到终点剩余容量不为0的路径。

把这条路径灌满水统计一下花费,之后再找新的路径,直到找不到为止。

数据结构方面定义一个构造体表示中两个相邻点的容量,流量和所需费用。

之后定义一个二位数组来标识点和点之间的相邻关系。

代码:

  #include <iostream>  using namespace std;struct Node{int cap, flow, cost;};Node edge[100][100];int sum;int size = 7;int s = 0, t = 6, a=0;int pre[10];int q[200];int vis[10], dis[10];void init(){int i, j;for(i = 0; i < size; i++)for(j = 0; j < size; j++){edge[i][j].cost = 100000;edge[i][j].flow = 0;edge[i][j].cap = 0;}edge[0][1].cost = 0; edge[0][1].cap = 10000;edge[1][3].cost = 2; edge[1][3].cap = 8;edge[1][2].cost = 8; edge[1][2].cap = 7;edge[3][2].cost = 5; edge[3][2].cap = 5;edge[3][5].cost = 2; edge[3][5].cap = 9;edge[2][4].cost = 3; edge[2][4].cap = 9;edge[5][2].cost = 1; edge[5][2].cap = 2;edge[5][6].cost = 6; edge[5][6].cap = 5;edge[4][6].cost = 7; edge[4][6].cap = 10;edge[4][5].cost = 4; edge[4][5].cap = 6;}int spfa(){int i, temp;for(i = 0; i < size; i++){vis[i] = -1;dis[i] = 100000;}int front = 0, tail= 1;vis[s] = 1; dis[s] = 0;q[front] = s;while(front < tail){temp = q[front];vis[temp] = -1;front++;for(i = 0; i < size; i++){int res = edge[temp][i].cap - edge[temp][i].flow;if(res > 0 && dis[i] > dis[temp] + edge[temp][i].cost){dis[i] = dis[temp] + edge[temp][i].cost;pre[i] =temp;    if(vis[i] == -1)    {    vis[i] = 1;    q[tail++] = i;    }}}}return dis[t];}int MCMF(){int temp, min, flow, sum = 0, cost, val;while(spfa() < 8000){   temp = t; flow = 100000; cost = 0;while(temp != s){val = edge[pre[temp]][temp].cap - edge[pre[temp]][temp].flow;cost += edge[pre[temp]][temp].cost;if(val < flow)flow = val;temp = pre[temp];}temp = t;cout << flow << " " << cost << endl;sum += flow * cost;while(temp != s){edge[pre[temp]][temp].flow += flow;edge[temp][pre[temp]].flow -= flow;//cout << pre[temp] << " " << temp << " ";//cout << edge[pre[temp]][temp].flow << endl;temp = pre[temp];}}return sum;}int main()  {  init();cout << MCMF() << endl;    return 0;  }




0 0
原创粉丝点击