From bb6970bbb58d38ab01498cb66466edd8b63e47cf Mon Sep 17 00:00:00 2001 From: wheson Date: Sat, 31 Mar 2018 23:17:21 +0900 Subject: [PATCH 01/15] =?UTF-8?q?Dinic=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AE?= =?UTF-8?q?=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/Graph/dinic.cpp | 76 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 lib/Graph/dinic.cpp diff --git a/lib/Graph/dinic.cpp b/lib/Graph/dinic.cpp new file mode 100644 index 0000000..928383f --- /dev/null +++ b/lib/Graph/dinic.cpp @@ -0,0 +1,76 @@ +#include "template.h" + +struct Edge { + int to; + long long cap; + int rev; +}; + +class Dinic { + private: + int V; // 頂点数 + vector minCost; + vector iter; + vector> graph; + const long long INFl = 1e15; + bool Bfs(int s, int t); + long long Dfs(int idx, const int t, long long flow); + + public: + Dinic(int n); + void AddEdge(int from, int to, long long cap); + long long Run(int s, int t); +}; + +Dinic::Dinic(int n) : V(n) { graph.assign(V, vector()); } + +void Dinic::AddEdge(int from, int to, long long cap) { + graph[from].push_back((Edge){to, cap, (int)graph[to].size()}); + graph[to].push_back((Edge){from, 0, (int)graph[from].size() - 1}); +} + +bool Dinic::Bfs(int s, int t) { + minCost.assign(graph.size(), -1); + queue que; + minCost[s] = 0; + que.push(s); + while (!que.empty()) { + int p = que.front(); + que.pop(); + for (auto &e : graph[p]) { + if (e.cap > 0 && minCost[e.to] < 0) { + minCost[e.to] = minCost[p] + 1; + que.push(e.to); + } + } + } + return (minCost[t] != -1); +} + +long long Dinic::Dfs(int idx, const int t, long long flow) { + if (idx == t) return flow; + for (int &i = iter[idx]; i < (int)graph[idx].size(); ++i) { + Edge &e = graph[idx][i]; + if (e.cap > 0 && minCost[idx] < minCost[e.to]) { + long long d = Dfs(e.to, t, min(flow, e.cap)); + if (d > 0) { + e.cap -= d; + graph[e.to][e.rev].cap += d; + return d; + } + } + } + return 0; +} + +long long Dinic::Run(int s, int t) { + long long flow = 0; + while (Bfs(s, t)) { + iter.assign(graph.size(), 0); + long long f = 0; + while ((f = Dfs(s, t, INFl)) > 0) { + flow += f; + } + } + return flow; +} From 1728a8301caf2b0c2ad13099309f69b3f39e0dba Mon Sep 17 00:00:00 2001 From: wheson Date: Sat, 31 Mar 2018 23:18:24 +0900 Subject: [PATCH 02/15] long long -> Int --- lib/Graph/dinic.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/Graph/dinic.cpp b/lib/Graph/dinic.cpp index 928383f..13ef79d 100644 --- a/lib/Graph/dinic.cpp +++ b/lib/Graph/dinic.cpp @@ -2,29 +2,29 @@ struct Edge { int to; - long long cap; + Int cap; int rev; }; class Dinic { private: int V; // 頂点数 - vector minCost; + vector minCost; vector iter; vector> graph; - const long long INFl = 1e15; + const Int INFl = 1e15; bool Bfs(int s, int t); - long long Dfs(int idx, const int t, long long flow); + Int Dfs(int idx, const int t, Int flow); public: Dinic(int n); - void AddEdge(int from, int to, long long cap); - long long Run(int s, int t); + void AddEdge(int from, int to, Int cap); + Int Run(int s, int t); }; Dinic::Dinic(int n) : V(n) { graph.assign(V, vector()); } -void Dinic::AddEdge(int from, int to, long long cap) { +void Dinic::AddEdge(int from, int to, Int cap) { graph[from].push_back((Edge){to, cap, (int)graph[to].size()}); graph[to].push_back((Edge){from, 0, (int)graph[from].size() - 1}); } @@ -47,12 +47,12 @@ bool Dinic::Bfs(int s, int t) { return (minCost[t] != -1); } -long long Dinic::Dfs(int idx, const int t, long long flow) { +Int Dinic::Dfs(int idx, const int t, Int flow) { if (idx == t) return flow; for (int &i = iter[idx]; i < (int)graph[idx].size(); ++i) { Edge &e = graph[idx][i]; if (e.cap > 0 && minCost[idx] < minCost[e.to]) { - long long d = Dfs(e.to, t, min(flow, e.cap)); + Int d = Dfs(e.to, t, min(flow, e.cap)); if (d > 0) { e.cap -= d; graph[e.to][e.rev].cap += d; @@ -63,11 +63,11 @@ long long Dinic::Dfs(int idx, const int t, long long flow) { return 0; } -long long Dinic::Run(int s, int t) { - long long flow = 0; +Int Dinic::Run(int s, int t) { + Int flow = 0; while (Bfs(s, t)) { iter.assign(graph.size(), 0); - long long f = 0; + Int f = 0; while ((f = Dfs(s, t, INFl)) > 0) { flow += f; } From f268fcc054489be29aaf093266fe2ec47cc8f314 Mon Sep 17 00:00:00 2001 From: wheson Date: Sat, 31 Mar 2018 23:22:47 +0900 Subject: [PATCH 03/15] explicit and () --- lib/Graph/dinic.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Graph/dinic.cpp b/lib/Graph/dinic.cpp index 13ef79d..942e423 100644 --- a/lib/Graph/dinic.cpp +++ b/lib/Graph/dinic.cpp @@ -17,7 +17,7 @@ class Dinic { Int Dfs(int idx, const int t, Int flow); public: - Dinic(int n); + explicit Dinic(int n); void AddEdge(int from, int to, Int cap); Int Run(int s, int t); }; @@ -25,8 +25,8 @@ class Dinic { Dinic::Dinic(int n) : V(n) { graph.assign(V, vector()); } void Dinic::AddEdge(int from, int to, Int cap) { - graph[from].push_back((Edge){to, cap, (int)graph[to].size()}); - graph[to].push_back((Edge){from, 0, (int)graph[from].size() - 1}); + graph[from].push_back((Edge){to, cap, (graph[to].size())}); + graph[to].push_back((Edge){from, 0, (graph[from].size() - 1)}); } bool Dinic::Bfs(int s, int t) { @@ -49,7 +49,7 @@ bool Dinic::Bfs(int s, int t) { Int Dinic::Dfs(int idx, const int t, Int flow) { if (idx == t) return flow; - for (int &i = iter[idx]; i < (int)graph[idx].size(); ++i) { + for (int &i = iter[idx]; i < (graph[idx].size()); ++i) { Edge &e = graph[idx][i]; if (e.cap > 0 && minCost[idx] < minCost[e.to]) { Int d = Dfs(e.to, t, min(flow, e.cap)); From 923a3025d3d2485fbcbbb0d0a658b0036ad03979 Mon Sep 17 00:00:00 2001 From: wheson Date: Sat, 31 Mar 2018 23:27:34 +0900 Subject: [PATCH 04/15] static_cast() --- lib/Graph/dinic.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/Graph/dinic.cpp b/lib/Graph/dinic.cpp index 942e423..4e5e735 100644 --- a/lib/Graph/dinic.cpp +++ b/lib/Graph/dinic.cpp @@ -25,8 +25,9 @@ class Dinic { Dinic::Dinic(int n) : V(n) { graph.assign(V, vector()); } void Dinic::AddEdge(int from, int to, Int cap) { - graph[from].push_back((Edge){to, cap, (graph[to].size())}); - graph[to].push_back((Edge){from, 0, (graph[from].size() - 1)}); + graph[from].push_back((Edge){to, cap, static_cast(graph[to].size())}); + graph[to].push_back( + (Edge){from, 0, static_cast(graph[from].size() - 1)}); } bool Dinic::Bfs(int s, int t) { @@ -49,7 +50,7 @@ bool Dinic::Bfs(int s, int t) { Int Dinic::Dfs(int idx, const int t, Int flow) { if (idx == t) return flow; - for (int &i = iter[idx]; i < (graph[idx].size()); ++i) { + for (int &i = iter[idx]; i < static_cast(graph[idx].size()); ++i) { Edge &e = graph[idx][i]; if (e.cap > 0 && minCost[idx] < minCost[e.to]) { Int d = Dfs(e.to, t, min(flow, e.cap)); From df1cc4ba0f8bd48d0eb221fb4683d59c4b6c9945 Mon Sep 17 00:00:00 2001 From: wheson Date: Sun, 1 Apr 2018 17:25:22 +0900 Subject: [PATCH 05/15] =?UTF-8?q?template=E3=81=AB=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/Graph/dinic.cpp | 47 +++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/lib/Graph/dinic.cpp b/lib/Graph/dinic.cpp index 4e5e735..6c5e84f 100644 --- a/lib/Graph/dinic.cpp +++ b/lib/Graph/dinic.cpp @@ -1,36 +1,43 @@ #include "template.h" +template struct Edge { int to; - Int cap; + T cap; int rev; }; +template class Dinic { private: int V; // 頂点数 - vector minCost; + vector minCost; vector iter; - vector> graph; - const Int INFl = 1e15; + vector>> graph; + const T INF = numeric_limits::max(); bool Bfs(int s, int t); - Int Dfs(int idx, const int t, Int flow); + T Dfs(int idx, const int t, T flow); public: explicit Dinic(int n); - void AddEdge(int from, int to, Int cap); - Int Run(int s, int t); + void AddEdge(int from, int to, T cap); + T Run(int s, int t); }; -Dinic::Dinic(int n) : V(n) { graph.assign(V, vector()); } +template +Dinic::Dinic(int n) : V(n) { + graph.assign(V, vector>()); +} -void Dinic::AddEdge(int from, int to, Int cap) { - graph[from].push_back((Edge){to, cap, static_cast(graph[to].size())}); +template +void Dinic::AddEdge(int from, int to, T cap) { + graph[from].push_back((Edge){to, cap, static_cast(graph[to].size())}); graph[to].push_back( - (Edge){from, 0, static_cast(graph[from].size() - 1)}); + (Edge){from, 0, static_cast(graph[from].size() - 1)}); } -bool Dinic::Bfs(int s, int t) { +template +bool Dinic::Bfs(int s, int t) { minCost.assign(graph.size(), -1); queue que; minCost[s] = 0; @@ -48,12 +55,13 @@ bool Dinic::Bfs(int s, int t) { return (minCost[t] != -1); } -Int Dinic::Dfs(int idx, const int t, Int flow) { +template +T Dinic::Dfs(int idx, const int t, T flow) { if (idx == t) return flow; for (int &i = iter[idx]; i < static_cast(graph[idx].size()); ++i) { - Edge &e = graph[idx][i]; + Edge &e = graph[idx][i]; if (e.cap > 0 && minCost[idx] < minCost[e.to]) { - Int d = Dfs(e.to, t, min(flow, e.cap)); + T d = Dfs(e.to, t, min(flow, e.cap)); if (d > 0) { e.cap -= d; graph[e.to][e.rev].cap += d; @@ -64,12 +72,13 @@ Int Dinic::Dfs(int idx, const int t, Int flow) { return 0; } -Int Dinic::Run(int s, int t) { - Int flow = 0; +template +T Dinic::Run(int s, int t) { + T flow = 0; while (Bfs(s, t)) { iter.assign(graph.size(), 0); - Int f = 0; - while ((f = Dfs(s, t, INFl)) > 0) { + T f = 0; + while ((f = Dfs(s, t, INF)) > 0) { flow += f; } } From 9898d04338fb8c00b3d06da5136310960ebbde2a Mon Sep 17 00:00:00 2001 From: wheson Date: Sun, 1 Apr 2018 18:47:08 +0900 Subject: [PATCH 06/15] =?UTF-8?q?Edge=E3=81=AE=E3=82=B3=E3=83=B3=E3=82=B9?= =?UTF-8?q?=E3=83=88=E3=83=A9=E3=82=AF=E3=82=BF=E3=82=92=E6=9B=B8=E3=81=84?= =?UTF-8?q?=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/Graph/dinic.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Graph/dinic.cpp b/lib/Graph/dinic.cpp index 6c5e84f..f1b49df 100644 --- a/lib/Graph/dinic.cpp +++ b/lib/Graph/dinic.cpp @@ -5,6 +5,7 @@ struct Edge { int to; T cap; int rev; + Edge(int to, T cap, int rev) : to(to), cap(cap), rev(rev) {} }; template From c4148e3d9609fcfaf694c2eb83bf6988e0a40677 Mon Sep 17 00:00:00 2001 From: wheson Date: Sun, 1 Apr 2018 18:49:16 +0900 Subject: [PATCH 07/15] =?UTF-8?q?=E3=81=A1=E3=82=87=E3=81=84=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/Graph/dinic.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Graph/dinic.cpp b/lib/Graph/dinic.cpp index f1b49df..1ae9417 100644 --- a/lib/Graph/dinic.cpp +++ b/lib/Graph/dinic.cpp @@ -32,9 +32,9 @@ Dinic::Dinic(int n) : V(n) { template void Dinic::AddEdge(int from, int to, T cap) { - graph[from].push_back((Edge){to, cap, static_cast(graph[to].size())}); + graph[from].push_back(Edge(to, cap, static_cast(graph[to].size()))); graph[to].push_back( - (Edge){from, 0, static_cast(graph[from].size() - 1)}); + Edge(from, 0, static_cast(graph[from].size() - 1))); } template From 4fa1cdfa57c65b46ba116c80909fbf4bef08e0e4 Mon Sep 17 00:00:00 2001 From: wheson Date: Sat, 21 Apr 2018 10:35:29 +0900 Subject: [PATCH 08/15] =?UTF-8?q?graph.h=E3=82=92include=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/Graph/dinic.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/lib/Graph/dinic.cpp b/lib/Graph/dinic.cpp index 1ae9417..88204f3 100644 --- a/lib/Graph/dinic.cpp +++ b/lib/Graph/dinic.cpp @@ -1,12 +1,5 @@ #include "template.h" - -template -struct Edge { - int to; - T cap; - int rev; - Edge(int to, T cap, int rev) : to(to), cap(cap), rev(rev) {} -}; +#include "graph.h" template class Dinic { From 765cac74c0f415f2eb1a921c0b4b135c9b7512f9 Mon Sep 17 00:00:00 2001 From: wheson Date: Sat, 21 Apr 2018 10:37:12 +0900 Subject: [PATCH 09/15] =?UTF-8?q?AdjList=E3=81=A8=E3=81=97=E3=81=A6graph?= =?UTF-8?q?=E3=82=92=E5=AE=A3=E8=A8=80,=20INF=E3=82=92/10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/Graph/dinic.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Graph/dinic.cpp b/lib/Graph/dinic.cpp index 88204f3..ae9c8ef 100644 --- a/lib/Graph/dinic.cpp +++ b/lib/Graph/dinic.cpp @@ -7,8 +7,8 @@ class Dinic { int V; // 頂点数 vector minCost; vector iter; - vector>> graph; - const T INF = numeric_limits::max(); + AdjList graph; + const T INF = numeric_limits::max() / 10; bool Bfs(int s, int t); T Dfs(int idx, const int t, T flow); From b6bdcc5f3bb05cccdc46bafe94aee70d10f240fe Mon Sep 17 00:00:00 2001 From: wheson Date: Sat, 21 Apr 2018 10:38:37 +0900 Subject: [PATCH 10/15] =?UTF-8?q?graph=E3=81=AE=E3=82=B5=E3=82=A4=E3=82=BA?= =?UTF-8?q?=E3=81=AE=E5=88=9D=E6=9C=9F=E5=8C=96=E6=96=B9=E6=B3=95=E3=82=92?= =?UTF-8?q?=E5=8D=98=E7=B4=94=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/Graph/dinic.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/Graph/dinic.cpp b/lib/Graph/dinic.cpp index ae9c8ef..2487a81 100644 --- a/lib/Graph/dinic.cpp +++ b/lib/Graph/dinic.cpp @@ -19,9 +19,7 @@ class Dinic { }; template -Dinic::Dinic(int n) : V(n) { - graph.assign(V, vector>()); -} +Dinic::Dinic(int n) : V(n), graph(n) {} template void Dinic::AddEdge(int from, int to, T cap) { From 1f8c63237525fb7d7cc202870a53d2cf890d397e Mon Sep 17 00:00:00 2001 From: wheson Date: Sat, 21 Apr 2018 10:40:25 +0900 Subject: [PATCH 11/15] =?UTF-8?q?cap=E3=82=92cost=E3=81=AB(graph.h?= =?UTF-8?q?=E3=82=92=E5=88=A9=E7=94=A8=E3=81=99=E3=82=8B=E3=81=9F=E3=82=81?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/Graph/dinic.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/Graph/dinic.cpp b/lib/Graph/dinic.cpp index 2487a81..2b04927 100644 --- a/lib/Graph/dinic.cpp +++ b/lib/Graph/dinic.cpp @@ -14,7 +14,7 @@ class Dinic { public: explicit Dinic(int n); - void AddEdge(int from, int to, T cap); + void AddEdge(int from, int to, T cost); T Run(int s, int t); }; @@ -22,10 +22,10 @@ template Dinic::Dinic(int n) : V(n), graph(n) {} template -void Dinic::AddEdge(int from, int to, T cap) { - graph[from].push_back(Edge(to, cap, static_cast(graph[to].size()))); +void Dinic::AddEdge(int from, int to, T cost) { + graph[from].push_back(Edge(static_cast(graph[to].size()), to, cost)); graph[to].push_back( - Edge(from, 0, static_cast(graph[from].size() - 1))); + Edge(static_cast(graph[from].size() - 1), from, 0)); } template @@ -38,7 +38,7 @@ bool Dinic::Bfs(int s, int t) { int p = que.front(); que.pop(); for (auto &e : graph[p]) { - if (e.cap > 0 && minCost[e.to] < 0) { + if (e.cost > 0 && minCost[e.to] < 0) { minCost[e.to] = minCost[p] + 1; que.push(e.to); } @@ -52,11 +52,11 @@ T Dinic::Dfs(int idx, const int t, T flow) { if (idx == t) return flow; for (int &i = iter[idx]; i < static_cast(graph[idx].size()); ++i) { Edge &e = graph[idx][i]; - if (e.cap > 0 && minCost[idx] < minCost[e.to]) { - T d = Dfs(e.to, t, min(flow, e.cap)); + if (e.cost > 0 && minCost[idx] < minCost[e.to]) { + T d = Dfs(e.to, t, min(flow, e.cost)); if (d > 0) { - e.cap -= d; - graph[e.to][e.rev].cap += d; + e.cost -= d; + graph[e.to][e.from].cost += d; return d; } } From 96bbd4c3233e178944553cc67e07fcdf32c4e960 Mon Sep 17 00:00:00 2001 From: wheson Date: Sat, 21 Apr 2018 10:41:46 +0900 Subject: [PATCH 12/15] =?UTF-8?q?make=20format=E3=82=92=E5=AE=9F=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/Graph/dinic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Graph/dinic.cpp b/lib/Graph/dinic.cpp index 2b04927..6788852 100644 --- a/lib/Graph/dinic.cpp +++ b/lib/Graph/dinic.cpp @@ -1,5 +1,5 @@ -#include "template.h" #include "graph.h" +#include "template.h" template class Dinic { From 3e3495be1900259d225cc096358ce1a4e97dac06 Mon Sep 17 00:00:00 2001 From: wheson Date: Sat, 21 Apr 2018 18:23:12 +0900 Subject: [PATCH 13/15] =?UTF-8?q?static=5Fcast=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/Graph/dinic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Graph/dinic.cpp b/lib/Graph/dinic.cpp index 6788852..181d27b 100644 --- a/lib/Graph/dinic.cpp +++ b/lib/Graph/dinic.cpp @@ -50,7 +50,7 @@ bool Dinic::Bfs(int s, int t) { template T Dinic::Dfs(int idx, const int t, T flow) { if (idx == t) return flow; - for (int &i = iter[idx]; i < static_cast(graph[idx].size()); ++i) { + for (int &i = iter[idx]; i < graph[idx].size(); ++i) { Edge &e = graph[idx][i]; if (e.cost > 0 && minCost[idx] < minCost[e.to]) { T d = Dfs(e.to, t, min(flow, e.cost)); From 9faa0440accd13a0e5a1af565a2e9785ff138769 Mon Sep 17 00:00:00 2001 From: wheson Date: Sat, 28 Apr 2018 19:10:22 +0900 Subject: [PATCH 14/15] .cpp -> .h --- lib/Graph/{dinic.cpp => dinic.h} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lib/Graph/{dinic.cpp => dinic.h} (100%) diff --git a/lib/Graph/dinic.cpp b/lib/Graph/dinic.h similarity index 100% rename from lib/Graph/dinic.cpp rename to lib/Graph/dinic.h From 0b09327838c0588a0de8822c3333a3d9a0da0412 Mon Sep 17 00:00:00 2001 From: wheson Date: Sat, 28 Apr 2018 19:10:55 +0900 Subject: [PATCH 15/15] #pragma once --- lib/Graph/dinic.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Graph/dinic.h b/lib/Graph/dinic.h index 181d27b..f2ffa85 100644 --- a/lib/Graph/dinic.h +++ b/lib/Graph/dinic.h @@ -1,3 +1,4 @@ +#pragma once #include "graph.h" #include "template.h"