网络流模板--spfa
来源:互联网 发布:mac pdf阅读器 中文版 编辑:程序博客网 时间:2024/05/17 02:11
/* *用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;}