/*
*用spfa去求最小费用流,首先是找到最小费用,然后通过最小费用求最大流
*/
struct Edge {
int start;
int end;
int cap;
int cost;
int next;
};
struct Edge edge[MAX_EDGE];
int head[MAX_POINT], queue[MAX_POINT], pre_edge[MAX_POINT];
int spfa() {
int i, cnt_point, next_point, next_edge, front, rear;
for (i = 0; i <= point_number; i++) {
distance[i] = INF;
}
memset(vis, 0, sizeof(vis));
/*入队*/
vis[source] = 1;
distance[source] = 0;
front = 0;
rear = 1;
queue[front] = source;
/*找到最小费用*/
while (front < rear) {
cnt_point = queue[front];
vis[cnt_point] = 1;
for (next_edge = head[cnt_point]; next_edge != -1; next_edge = edge[next_edge].next) {
next_point = edge[next_edge].end;
if (edge[next_edge].cap > 0 && distance[next_point] > distance[cnt_point] + edge[next_edge].cost) {
distance[next_point] = distance[cnt_point] + edge[next_edge];
/*记录更新此费用的边号*/
pre_edge[next_point] = next_edge;
if (!vis[next_point]) {
queue[rear] = next_point;
rear++;
rear = rear % QUEUE_LENTH;
}
}
}
front++;
front = front % QUEUE_LENTH;
vis[cnt_point] = 0;
}
/*找不到最小费用了*/
if (distance[destination] == INF) {
return 0;
}
min_flow = INF;
/*找到最小费用之后找到可以通过的最大流*/
for (i = destination; i != source; i = edge[pre_edge_number].start) {
pre_edge_number = pre_edge[i];
if (min_flow > edge[pre_edge_number].cap) {
min_flow = edge[pre_edge_number].cap;
}
}
for (i = destination; i != source; i = edge[pre_edge_number].start) {
pre_edge_number = pre_edge[i];
edge[pre_edge_number].cap -= min_flow;
edge[pre_edge_number ^ 1].cap += min_flow;
costs += edge[pre_edge_number].cost * min_flow;
}
flow += min_flow;
return 1;
}
网络流模板--spfa
最新推荐文章于 2022-08-22 23:02:01 发布