Brine
A certain person trying to make his way in the universe.
22527 鄭竣陽
Brine
BrineTW#7355
Index
Glossary
Maximum Flow
Max-Flow Min-Cut
Max Flow Algorithm
typedef long long ll;
struct FordFulkerson {
int s, t, V;
vector< vector<int> > graph;
vector< vector<ll> > cap;
vector<bool> visited;
FordFulkerson(int V): V(V), graph(V), visited(V) {
cap.resize(V, vector<ll>(V));
}
void addEdge(int u, int v, int w) {
graph[u].push_back(v);
graph[v].push_back(u);
cap[u][v] += w;
}
ll dfs(int u, ll f = INT64_MAX) {
if (u == t) return f;
visited[u] = 1;
for (auto& v: graph[u]) {
if (cap[u][v] == 0 || visited[v]) continue;
ll fv = dfs(v, min(f, cap[u][v]));
if (fv) {
cap[u][v] -= fv;
cap[v][u] += fv;
return fv;
}
}
return 0;
}
ll maximumFlow(int s, int t) {
this->s = s, this->t = t;
ll f = 0;
for (ll augFlow; augFlow = dfs(s); f += augFlow) {
visited.assign(V, 0);
}
return f;
}
};
typedef long long ll;
struct EdmondsKarp {
int V;
vector< vector<ll> > cap;
vector< vector<int> > graph;
vector<int> p;
EdmondsKarp(int V): V(V), graph(V), p(V) {
cap.resize(V, vector<ll>(V));
}
void addEdge(int u, int v, int w) {
graph[u].push_back(v);
graph[v].push_back(u);
cap[u][v] += w;
}
bool bfs(int s, int t) {
p.assign(V, 0);
queue<int> q;
q.push(s);
while (q.size()) {
auto u = q.front();
q.pop();
for (auto& v: graph[u]) {
if (p[v] || !cap[u][v]) continue;
p[v] = u;
if (v == t) return 1;
q.push(v);
}
}
return 0;
}
ll maximumFlow(int s, int t) {
ll f = 0;
while (bfs(s, t)) {
ll augFlow = INT64_MAX;
for (int u = t; u != s; u = p[u]) {
augFlow = min(augFlow, cap[p[u]][u]);
}
for (int u = t; u != s; u = p[u]) {
cap[p[u]][u] -= augFlow;
cap[u][p[u]] += augFlow;
}
f += augFlow;
}
return f;
}
};
Dinitz
typedef long long ll;
struct Dinitz {
int s, t, V;
vector< vector<int> > graph;
vector< vector<ll> > cap;
vector<int> level, toCheck;
Dinitz(int V): V(V), graph(V), level(V), toCheck(V) {
cap.resize(V, vector<ll>(V));
}
void addEdge(int u, int v, int w) {
graph[u].push_back(v);
graph[v].push_back(u);
cap[u][v] += w;
}
int bfs() {
level.assign(V, 0);
level[s] = 1;
queue<int> q;
q.push(s);
while (q.size()) {
int u = q.front();
q.pop();
for (auto& v: graph[u]) {
if (level[v] || !cap[u][v]) continue;
level[v] = level[u] + 1;
q.push(v);
}
}
return level[t];
}
ll dfs(int u, ll f = INT64_MAX) {
if (u == t) return f;
for (auto& i = toCheck[u]; i < graph[u].size(); i++) {
auto& v = graph[u][i];
if (!cap[u][v] || level[v] != level[u] + 1) continue;
ll fv = dfs(v, min(f, cap[u][v]));
if (fv) {
cap[u][v] -= fv;
cap[v][u] += fv;
return fv;
}
}
return 0;
}
ll maximumFlow(int s, int t) {
this->s = s, this->t = t;
ll f = 0, augFlow;
while (bfs()) {
fill(toCheck.begin(), toCheck.end(), 0);
while (augFlow = dfs(s)) f += augFlow;
}
return f;
}
};
Push Relabel
typedef long long ll;
struct PushRelabel {
int V, i;
vector<vector<int>> graph, Q;
vector<vector<ll>> cap;
vector<int> h;
vector<ll> excess;
vector<bool> active;
PushRelabel(int V): V(V), graph(V), Q(V << 1 ^ 1), h(V), excess(V), active(V) {
cap.resize(V, vector<ll>(V));
}
void addEdge(int u, int v, int w) {
graph[u].push_back(v);
graph[v].push_back(u);
cap[u][v] += w;
}
void enqueue(int u) {
if (!active[u] && excess[u]) {
active[u] = 1;
Q[h[u]].push_back(u);
i = max(i, h[u]);
}
}
void push(int u, int v) {
ll f = min(excess[u], cap[u][v]);
if (h[u] > h[v] && f) {
cap[u][v] -= f;
cap[v][u] += f;
excess[v] += f;
excess[u] -= f;
enqueue(v);
}
}
void relabel(int u) {
h[u] = V * 2 + 1;
for (auto& v: graph[u]) if (cap[u][v]) {
h[u] = min(h[u], h[v] + 1);
}
enqueue(u);
}
void discharge(int u) {
for (auto& v: graph[u]) {
if (!excess[u]) break;
push(u, v);
}
if (excess[u]) relabel(u);
}
ll maximumFlow(int s, int t) {
excess[s] = INT64_MAX;
h[s] = V;
active[s] = active[t] = 1;
for (auto& v: graph[s]) push(s, v);
for (i = 0; i >= 0; i--) {
while (Q[i].size()) {
int u = Q[i].back();
Q[i].pop_back();
active[u] = 0;
discharge(u);
}
}
return excess[t];
}
};
struct PushRelabel {
int V, i;
vector<vector<int>> graph, Q;
vector<vector<ll>> cap;
vector<ll> excess;
vector<int> h, count;
vector<bool> active;
PushRelabel(int V): V(V), graph(V), Q(V), h(V), excess(V), count(V + 1), active(V) {
cap.resize(V, vector<ll>(V));
}
void addEdge(int u, int v, int w) {
graph[u].push_back(v);
graph[v].push_back(u);
cap[u][v] += w;
}
void enqueue(int u) {
if (!active[u] && excess[u] && h[u] < V) {
active[u] = 1;
Q[h[u]].push_back(u);
i = max(i, h[u]);
}
}
void push(int u, int v) {
ll f = min(excess[u], cap[u][v]);
if (h[u] == h[v] + 1 && f) {
cap[u][v] -= f;
cap[v][u] += f;
excess[v] += f;
excess[u] -= f;
enqueue(v);
}
}
void gap(int k) {
for (int u = 0; u < V; u++) if (h[u] >= k) {
count[h[u]]--;
h[u] = max(h[u], V);
count[h[u]]++;
enqueue(u);
}
}
void relabel(int u) {
count[h[u]]--;
h[u] = V;
for (auto& v: graph[u]) if (cap[u][v]) {
h[u] = min(h[u], h[v] + 1);
}
count[h[u]]++;
enqueue(u);
}
void discharge(int u) {
for (auto& v: graph[u]) {
if (!excess[u]) break;
push(u, v);
}
if (excess[u]) (count[h[u]] == 1) ? gap(h[u]) : relabel(u);
}
ll maximumFlow(int s, int t) {
excess[s] = INT64_MAX;
count[0] = V;
enqueue(s);
active[t] = 1;
for (i = 0; i >= 0; i--) {
while (Q[i].size()) {
int u = Q[i].back();
Q[i].pop_back();
active[u] = 0;
discharge(u);
}
}
return excess[t];
}
};
聽說,每次有人在建國中學資訊讀書會遇到看不懂的圖論概念的時候,就會有一位不知名先生出現,在你最絕望的時候從你背後輕拍你的肩膀,當你在想「到底是誰設計出這個演算法的啦幹」的時候,他就會到你的耳邊輕輕跟你說:
聽說,每次有人在建國中學資訊讀書會遇到看不懂的圖論概念的時候,就會有一位不知名先生出現,在你最絕望的時候從你背後輕拍你的肩膀,當你在想「到底是誰設計出這個演算法的啦幹」的時候,他就會到你的耳邊輕輕跟你說:
「哈哈,是我啦」
聽說,每次有人在建國中學資訊讀書會遇到看不懂的圖論概念的時候,就會有一位不知名先生出現,在你最絕望的時候從你背後輕拍你的肩膀,當你在想「到底是誰設計出這個演算法的啦幹」的時候,他就會到你的耳邊輕輕跟你說:
「哈哈,是我啦」
Solutions
struct Dinitz {
struct Edge {
int v, c, r;
Edge(int v, int c, int r): v(v), c(c), r(r) {}
};
int s, t, V;
vector< vector<Edge> > graph;
vector<int> level, toCheck;
Dinitz(int V): V(V), graph(V), level(V), toCheck(V) {}
void addEdge(int u, int v, int w) {
graph[u].push_back({v, w, graph[v].size()});
graph[v].push_back({u, 0, graph[u].size() - 1});
}
int bfs() {
level.assign(V, 0);
level[s] = 1;
queue<int> q;
q.push(s);
while (q.size()) {
int u = q.front();
q.pop();
for (auto& [v, c, r]: graph[u]) {
if (level[v] || !c) continue;
level[v] = level[u] + 1;
q.push(v);
}
}
return level[t];
}
int dfs(int u, int f = INT32_MAX) {
if (u == t) return f;
for (auto& i = toCheck[u]; i < graph[u].size(); i++) {
auto& [v, c, r] = graph[u][i];
if (!c || level[v] != level[u] + 1) continue;
int fv = dfs(v, min(f, c));
if (fv) {
c -= fv;
graph[v][r].c += fv;
return fv;
}
}
return 0;
}
ll maximumFlow(int s, int t) {
this->s = s, this->t = t;
ll f = 0, augFlow;
while (bfs()) {
fill(toCheck.begin(), toCheck.end(), 0);
while (augFlow = dfs(s)) f += augFlow;
}
return f;
}
};
Min Cost Flow
typedef long long ll;
struct SuccessiveSP {
struct Edge {
int v, c, w, r;
Edge(int v, int c, int w, int r): v(v), c(c), w(w), r(r) {}
};
int V;
vector< vector<Edge> > graph;
vector<ll> d;
vector<int> p, edgeId;
vector<bool> visited, inQueue;
SuccessiveSP(int V): V(V), graph(V) {}
void addEdge(int u, int v, int c, int w) {
graph[u].emplace_back(v, c, w, graph[v].size());
graph[v].emplace_back(u, 0, -w, graph[u].size() - 1);
}
void reset() {
d.assign(V, INT64_MAX);
p.assign(V, 0);
edgeId.assign(V, 0);
visited.assign(V, 0);
inQueue.assign(V, 0);
}
pair<ll, ll> SPFA(int s, int t) {
reset();
d[s] = 0;
queue<int> q;
q.push(s);
while (q.size()) {
int u = q.front();
q.pop();
inQueue[u] = 0;
for (int i = 0; i < graph[u].size(); i++) {
auto& [v, c, w, r] = graph[u][i];
if (c && d[u] + w < d[v]) {
p[v] = u;
edgeId[v] = i;
d[v] = d[u] + w;
if (inQueue[v]) continue;
inQueue[v] = 1;
q.push(v);
}
}
}
if (d[t] == INT64_MAX) return {0, 0};
int f = INT32_MAX;
for (int u = t; u != s; u = p[u]) {
f = min(f, graph[p[u]][edgeId[u]].c);
}
for (int u = t; u != s; u = p[u]) {
graph[p[u]][edgeId[u]].c -= f;
graph[u][graph[p[u]][edgeId[u]].r].c += f;
}
return {f, d[t]};
}
};
Templates
typedef long long ll;
struct Dinitz {
struct Edge {
int v, c, r;
Edge(int v, int c, int r): v(v), c(c), r(r) {}
};
int s, t, V;
vector< vector<Edge> > graph;
vector<int> level, toCheck;
Dinitz(int V): V(V), graph(V), level(V), toCheck(V) {}
void addEdge(int u, int v, int w) {
graph[u].push_back({v, w, graph[v].size()});
graph[v].push_back({u, 0, graph[u].size() - 1});
}
int bfs() {
level.assign(V, 0);
level[s] = 1;
queue<int> q;
q.push(s);
while (q.size()) {
int u = q.front();
q.pop();
for (auto& [v, c, r]: graph[u]) {
if (level[v] || !c) continue;
level[v] = level[u] + 1;
q.push(v);
}
}
return level[t];
}
int dfs(int u, int f = INT32_MAX) {
if (u == t) return f;
for (auto& i = toCheck[u]; i < graph[u].size(); i++) {
auto& [v, c, r] = graph[u][i];
if (!c || level[v] != level[u] + 1) continue;
int fv = dfs(v, min(f, c));
if (fv) {
c -= fv;
graph[v][r].c += fv;
return fv;
}
}
return 0;
}
ll maximumFlow(int s, int t) {
this->s = s, this->t = t;
ll f = 0, augFlow;
while (bfs()) {
fill(toCheck.begin(), toCheck.end(), 0);
while (augFlow = dfs(s)) f += augFlow;
}
return f;
}
};
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct PushRelabel {
struct Edge {
int v, c, r;
Edge(int v, int c, int r): v(v), c(c), r(r) {}
};
int V, i;
vector< vector<Edge> > graph;
vector< vector<int> > Q;
vector<int> h;
vector<ll> excess;
vector<bool> active;
PushRelabel(int V): V(V), graph(V), Q(V << 1 ^ 1), h(V), excess(V), active(V) {}
void addEdge(int u, int v, int w) {
graph[u].push_back({v, w, graph[v].size()});
graph[v].push_back({u, 0, graph[u].size()});
}
void enqueue(int u) {
if (!active[u] && excess[u]) {
active[u] = 1;
Q[h[u]].push_back(u);
i = max(i, h[u]);
}
}
void push(int u, Edge& e) {
auto& [v, c, r] = e;
int f = min(int(excess[u]), c);
if (h[u] > h[v] && f) {
c -= f;
graph[v][r].c += f;
excess[v] += f;
excess[u] -= f;
enqueue(v);
}
}
void relabel(int u) {
h[u] = V * 2 + 1;
for (auto& [v, c, r]: graph[u]) if (c) {
h[u] = min(h[u], h[v] + 1);
}
enqueue(u);
}
void discharge(int u) {
for (auto& e: graph[u]) {
if (!excess[u]) break;
push(u, e);
}
if (excess[u]) relabel(u);
}
ll maximumFlow(int s, int t) {
excess[s] = INT64_MAX;
h[s] = V;
active[s] = active[t] = 1;
for (auto& v: graph[s]) push(s, v);
for (i = 0; i >= 0; i--) {
while (Q[i].size()) {
int u = Q[i].back();
Q[i].pop_back();
active[u] = 0;
discharge(u);
}
}
return excess[t];
}
};
int main() {
}
typedef long long ll;
struct SuccessiveSP {
struct Edge {
int v, c, w, r;
Edge(int v, int c, int w, int r): v(v), c(c), w(w), r(r) {}
};
int V;
vector< vector<Edge> > graph;
vector<ll> d;
vector<int> p, edgeId;
vector<bool> visited, inQueue;
SuccessiveSP(int V): V(V), graph(V) {}
void addEdge(int u, int v, int c, int w) {
graph[u].emplace_back(v, c, w, graph[v].size());
graph[v].emplace_back(u, 0, -w, graph[u].size() - 1);
}
void reset() {
d.assign(V, INT64_MAX);
p.assign(V, 0);
edgeId.assign(V, 0);
visited.assign(V, 0);
inQueue.assign(V, 0);
}
pair<ll, ll> SPFA(int s, int t) {
reset();
d[s] = 0;
queue<int> q;
q.push(s);
while (q.size()) {
int u = q.front();
q.pop();
inQueue[u] = 0;
for (int i = 0; i < graph[u].size(); i++) {
auto& [v, c, w, r] = graph[u][i];
if (c && d[u] + w < d[v]) {
p[v] = u;
edgeId[v] = i;
d[v] = d[u] + w;
if (inQueue[v]) continue;
inQueue[v] = 1;
q.push(v);
}
}
}
if (d[t] == INT64_MAX) return {0, 0};
int f = INT32_MAX;
for (int u = t; u != s; u = p[u]) {
f = min(f, graph[p[u]][edgeId[u]].c);
}
for (int u = t; u != s; u = p[u]) {
graph[p[u]][edgeId[u]].c -= f;
graph[u][graph[p[u]][edgeId[u]].r].c += f;
}
return {f, d[t]};
}
};
啪!沒了
By Brine
心流(Flow),亦譯神馳、沉浸,是 1975 年由奇克森特米哈伊·米哈伊所提出的心理學概念。其描述人類一種完全沉浸和完全投入於活動本身的心智狀態的振奮狀態。在適當的條件下,心流狀態可以變成催眠或欣喜若狂的恍惚狀態。一些科學家已將心流本身理解為一種恍惚。