/**
*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;
}
网络流模板--dinic
最新推荐文章于 2022-08-22 09:09:38 发布