网络流模板--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;}