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