网络流模板--dinic

来源:互联网 发布:adams软件云 编辑:程序博客网 时间:2024/05/11 12:29
/** *To get the max flow in a graph *Use the adjcent table to express the graph */struct Edge {    int start;    int end;    int cap;    int next;};struct Edge edge[MAX_EDGE];int cur[MAX_POINT];   /*保存检索的第一条边*/int queue[MAX_POINT * 4];  /*BFS过程中使用的队列*/int distance[MAX_POINT]; /*层次图中的距离,即每个点到源点的*/int stack[MAX_POINT];  /*DFS检索流过程中的边号*/int head[MAX_POINT]   /*节点i的首次边号*//*value_1表示正向边, value_2表示反向边*//*edge[0]的反向边为edge[1],edge[1]和edge[0]互为反向边,任何一个边i的反正边为i ^ 1*/void addEdge(int start, int end, int value_1, int value_2) {    edge[edge_number].start = start;    edge[edge_number].end = end;    edge[edge_number].cap = value_1;    edge[edge_number].next = head[start];    head[start] = edge_number;    edge_number++;    edge[edge_number].start = end;    edge[edge_number].end = start;    edge[edge_number].cap = value_2;    edge[edge_number].next = head[end];    head[end] = edge_number;    edge_number++;}int bfs() {    int front, rear, cnt_point, i, end;    front = 0;    rear = 1;    memset(distance, -1, sizeof(distance));    queue[front] = source;    distance[source] = 0;    while (front < rear) {        cnt_point = queue[front];        for (i = head[cnt_point]; i != -1; i = edge[i].next) {            end = edge[i].end;            /*有流量并且距离没有算过*/            if (edge[i].cap > 0 && distance[end] == -1) {                distance[end] = distance[cnt_point] + 1;                queue[rear] = end;                rear++;                /*遍历到了汇点*/                if (end == destination) {                    return 1;                }            }        }        front++;    }    return 0;}int dinic() {    int flow, i, top, source, min_flow, min_flow_number;    while (bfs()) {        memcpy(cur, head, sizeof(head));        /*清空栈*/        top = 0;        cnt_point = source; /*从source进行dfs*/        while (1) {            /*遍历到了汇点*/            if (cnt_point == destination) {                min_flow = INF;                /*找到最小流量的边*/                for (i = 0; i < top; i++) {                    if (min_flow > edge[stack[i]].cap) {                        min_flow = edge[stack[i]].cap;                        min_flow_number = i;                    }                }                /*更新流量*/                for (i = 0; i < top; i++) {                    edge[stack[i]].cap -= min_flow;                    edge[stack[i] ^ 1].cap += min_flow;                }                flow += min_flow;  /*更新最大流*/                top = min_flow_number;                /*从最小流量的点再重新开始dfs*/                cnt_point = edge[stack[top]].start;            }            /*不是汇点,进行dfs*/            for (i = cur[cnt_point]; i != -1; cur[cnt_point] = i = edge[i].next) {                if (edge[i].cap > 0 && distance[edge[i].end] == distance[cnt_point] + 1) {                    break;                }            }            /*找到了一个有流量且在下一个层次的边,边号入栈*/            if (cur[cnt_point] != -1) {                stack[top++] = cur[cnt_point];                cnt_point = edge[cur[cnt_point]].end;            }            /*没有找到的话*/            else {                if (top == 0) {                    break;                }                distance[cnt_point] = -1;   /*表明当前点无法深搜下去*/                top--;                /*回溯到上一个点*/                                cnt_point = edge[stack[top]].start;            }        }    }    return flow;}

原创粉丝点击