生活随笔
收集整理的這篇文章主要介紹了
网络流 (EK Dinic)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
- Edmonds-Karp
BFS找增廣路,找到增廣路,更新殘余網絡。
int G
[maxn
][maxn
], pre
[maxn
], vis
[maxn
], n
, m
;
bool bfs(int s
, int e
) {memset(vis
, 0, sizeof(vis
));memset(pre
, -1, sizeof(pre
));pre
[s
] = s
;vis
[s
] = 1;queue
<int> que
;que
.push(s
);while (!que
.empty()) {int u
= que
.front();que
.pop();for (int i
= 0; i
<= e
; i
++) {if (G
[u
][i
] && !vis
[i
]) {pre
[i
] = u
;que
.push(i
);vis
[i
] = 1;if (i
== e
) return 1; }}}return 0;
}
int EK(int s
, int e
) {int ans
= 0;while (bfs(s
, e
)) { int MIN
= inf
;for (int i
= e
; i
!= s
; i
= pre
[i
]) {MIN
= min(MIN
, G
[pre
[i
]][i
]);}for (int i
= e
; i
!= s
; i
= pre
[i
]) {G
[pre
[i
]][i
] -= MIN
;G
[i
][pre
[i
]] += MIN
;}ans
+= MIN
;}return ans
;
}
int cnt
;
struct ac
{int v
, c
, nex
;
}edge
[maxn
<< 8];
int vis
[maxn
], head
[maxn
], path
[maxn
];
void init() {cnt
= 0;memset(head
, -1, sizeof(head
));
}
void addedge(int u
, int v
, int c
) {edge
[cnt
] = {v
, c
, head
[u
]};head
[u
] = cnt
++;edge
[cnt
] = {u
, 0, head
[v
]};head
[v
] = cnt
++;
}
bool bfs(int s
, int t
) {memset(vis
, 0, sizeof(vis
));memset(path
, -1, sizeof(path
));queue
<int> que
;que
.push(s
);vis
[s
] = 1;while (!que
.empty()) {int u
= que
.front();que
.pop();for (int i
= head
[u
]; i
!= -1; i
= edge
[i
].nex
) {int v
= edge
[i
].v
;int c
= edge
[i
].c
;if (c
== 0 || vis
[v
]) continue;path
[v
] = i
;vis
[v
] = 1;que
.push(v
);if (v
== t
) return true;}}return false;
}
int EK(int s
, int t
) {int ans
= 0;while (bfs(s
, t
)) {int flow
= inf
;for (int i
= path
[t
]; i
!= -1; i
= path
[edge
[i
^1].v
]) {flow
= min(flow
, edge
[i
].c
);}for (int i
= path
[t
]; i
!= -1; i
= path
[edge
[i
^1].v
]) {edge
[i
].c
-= flow
;edge
[i
^1].c
+= flow
;} ans
+= flow
;}return ans
;
}
struct ac
{int v
, c
, nex
;
}edge
[maxn
<< ];
int s
, e
;
int head
[maxn
], dis
[maxn
], curedge
[maxn
], cnt
;
void init() {cnt
= 0;memset(head
, -1, sizeof(head
));
}
void addedge(int u
, int v
, int c
) {edge
[cnt
] = {v
, c
, head
[u
]};head
[u
] = cnt
++;edge
[cnt
] = {u
, 0, head
[v
]};head
[v
] = cnt
++;
}
bool bfs() {queue
<int> que
;que
.push(s
);memset(dis
, 0, sizeof(dis
)); dis
[s
] = 1;while (!que
.empty()) {int u
= que
.front();que
.pop();for (int i
= head
[u
]; i
!= -1; i
= edge
[i
].nex
) {int v
= edge
[i
].v
;int c
= edge
[i
].c
;if (dis
[v
] || c
== 0) continue;dis
[v
] = dis
[u
] + 1; que
.push(v
);}}return dis
[e
] > 0;
}int dfs(int u
, int flow
) { if (u
== e
|| flow
== 0) return flow
;for (int &i
= curedge
[u
]; i
!= -1; i
= edge
[i
].nex
) { int v
= edge
[i
].v
;int c
= edge
[i
].c
;if (dis
[v
] != dis
[u
] + 1 || c
== 0) continue;int d
= dfs(v
, min(flow
, c
));if (d
> 0) { edge
[i
].c
-= d
;edge
[i
^1].c
+= d
;return d
;} }dis
[u
] = -1; return 0;
}
int Dinic() {int sum
= 0, d
;while (bfs()) { for (int i
= 0; i
<= e
; ++i
) curedge
[i
] = head
[i
]; while ((d
= dfs(s
, inf
)) > 0) sum
+= d
; }return sum
;
}
總結
以上是生活随笔為你收集整理的网络流 (EK Dinic)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。