Skip to content

Commit f32707c

Browse files
committed
graph2を追加
1 parent 410bc56 commit f32707c

11 files changed

Lines changed: 558 additions & 0 deletions

File tree

‎Cpp/Graph2/Base.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
template <class E>
2+
using Graph = vector<vector<E>>;

‎Cpp/Graph2/Bridge.h‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* 橋の検出
3+
*/
4+
struct Bridge {
5+
int gc;
6+
vector<int> ig; // i to group
7+
vector<int> gpar; // group par
8+
9+
template<class E>
10+
void exec(const Graph<E> &g, int r) {
11+
int V = (int)g.size();
12+
LowLink lc(g, r);
13+
ig.resize(V);
14+
gc = 0;
15+
for (int p: lc.vlis) {
16+
if (lc.low[p] == lc.ord[p]) {
17+
ig[p] = gc++;
18+
gpar.push_back((p == r) ? -1 : ig[lc.par[p]]);
19+
} else {
20+
ig[p] = ig[lc.par[p]];
21+
}
22+
}
23+
}
24+
};

‎Cpp/Graph2/Dijkstra.h‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* Dijkstra法により最短距離を求める
3+
*
4+
* template引数のint Vは頂点数
5+
* ---
6+
* struct Edge {
7+
* int to;
8+
* T dist;
9+
* };
10+
* ---
11+
*/
12+
template<class D, D INF>
13+
struct Dijkstra {
14+
vector<D> res; //res[i] = sからiまでの最短距離
15+
16+
template<class E>
17+
void exec(const Graph<E> &g, int s) {
18+
int V = (int)g.size();
19+
res.resize(V); fill_n(res.begin(), V, INF);
20+
using P = pair<D, int>;
21+
priority_queue<P, vector<P>, greater<P>> q;
22+
q.push(P(0, s));
23+
res[s] = 0;
24+
while (!q.empty()) {
25+
P p = q.top(); q.pop();
26+
if (res[p.second] < p.first) continue;
27+
for (E e: g[p.second]) {
28+
if (p.first+e.dist < res[e.to]) {
29+
res[e.to] = p.first+e.dist;
30+
q.push(P(res[e.to], e.to));
31+
}
32+
}
33+
}
34+
}
35+
};

‎Cpp/Graph2/Dominator.h‎

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* Dominator Tree
3+
*/
4+
struct Dominator {
5+
vector<int> idom, sdom;
6+
7+
LowLink lc;
8+
9+
Dominator() {}
10+
template<class E>
11+
Dominator(const Graph<E> &g, const Graph<E> &rg, int s) {
12+
exec(g, rg, s);
13+
}
14+
15+
template<class E>
16+
void exec(const Graph<E> &g, const Graph<E> &rg, int s) {
17+
int V = (int)g.size();
18+
19+
lc = LowLink(g, 0);
20+
21+
// uf init
22+
p.resize(V); mv.resize(V);
23+
fill_n(p.begin(), V, -1);
24+
iota(mv.begin(), mv.end(), 0);
25+
idom.resize(V); sdom.resize(V);
26+
iota(sdom.begin(), sdom.end(), 0);
27+
28+
vector<int> up(V);
29+
vector<vector<int>> bucket(V);
30+
for (int i = V-1; i > 0; i--) {
31+
int u = lc.vlis[i];
32+
for (E e: rg[u]) {
33+
sdom[u] = lc.vlis[min(lc.ord[sdom[u]], lc.ord[sdom[compress(e.to)]])];
34+
}
35+
bucket[sdom[u]].push_back(u);
36+
for (int v: bucket[lc.par[u]]) {
37+
up[v] = compress(v);
38+
}
39+
bucket[lc.par[u]].clear();
40+
p[u] = lc.par[u]; // uf merge
41+
}
42+
43+
idom[s] = -1;
44+
for (int i = 1; i < V; i++) {
45+
int u = lc.vlis[i], v = up[u];
46+
if (sdom[u] == sdom[v]) idom[u] = sdom[u];
47+
else idom[u] = idom[v];
48+
}
49+
}
50+
51+
// unionfind
52+
vector<int> p, mv; // parent, min sdom's v
53+
int compress(int a) {
54+
if (p[a] != -1) {
55+
compress(p[a]);
56+
if (lc.ord[sdom[mv[a]]] > lc.ord[sdom[mv[p[a]]]]) {
57+
mv[a] = mv[p[a]];
58+
}
59+
p[a] = (p[p[a]] == -1 ? p[a] : p[p[a]]);
60+
}
61+
return mv[a];
62+
}
63+
};

‎Cpp/Graph2/LCA.h‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* LCA(lowest common ancestor)
3+
*/
4+
template<int LG = 20>
5+
struct LCA {
6+
vector<int> ro[LG], dps;
7+
8+
/// 事前処理を行う rはroot頂点のid
9+
template<class E>
10+
void exec(const Graph<E> &g, int r) {
11+
int V = (int)g.size();
12+
for (int i = 0; i < LG; i++) {
13+
ro[i].resize(V);
14+
fill_n(ro[i].begin(), V, -1);
15+
}
16+
dps.resize(V);
17+
dfs(g, r, -1, 0);
18+
for (int i = 1; i < LG; i++) {
19+
for (int j = 0; j < V; j++) {
20+
ro[i][j] = (ro[i-1][j] == -1) ? -1 : ro[i-1][ro[i-1][j]];
21+
}
22+
}
23+
}
24+
/// lとrの頂点のLCAを求める
25+
int query(int l, int r) {
26+
if (dps[l] < dps[r]) swap(l, r);
27+
int dd = dps[l]-dps[r];
28+
for (int i = LG-1; i >= 0; i--) {
29+
if (dd < (1<<i)) continue;
30+
dd -= 1<<i;
31+
l = ro[i][l];
32+
}
33+
if (l == r) return l;
34+
for (int i = LG-1; i >= 0; i--) {
35+
if (ro[i][l] == ro[i][r]) continue;
36+
l = ro[i][l]; r = ro[i][r];
37+
}
38+
return ro[0][l];
39+
}
40+
41+
template<class E>
42+
void dfs(const Graph<E> &g, int p, int b, int now) {
43+
ro[0][p] = b;
44+
dps[p] = now;
45+
for (E e: g[p]) {
46+
if (e.to == b) continue;
47+
dfs(g, e.to, p, now+1);
48+
}
49+
}
50+
};

‎Cpp/Graph2/LowLink.h‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* LowLink
3+
* dfs木についてのいろいろな情報を求める
4+
*/
5+
struct LowLink {
6+
vector<int> low, ord, par;
7+
vector<int> vlis;
8+
9+
LowLink() {}
10+
template<class E>
11+
LowLink(const Graph<E> &g, int r) { exec(g, r); }
12+
13+
template<class E>
14+
void exec(const Graph<E> &g, int r) {
15+
int V = (int)g.size();
16+
low.resize(V); ord.resize(V); par.resize(V);
17+
co = 0; used.resize(V);
18+
fill_n(used.begin(), V, false);
19+
if (r != -1) {
20+
dfs(g, r, -1);
21+
} else {
22+
for (int i = 0; i < n; i++) {
23+
if (used[i]) continue;
24+
dfs(g, i, -1);
25+
}
26+
}
27+
}
28+
int co;
29+
vector<bool> used;
30+
template<class E>
31+
void dfs(const Graph<E> &g, int p, int b) {
32+
used[p] = true;
33+
bool rt = true;
34+
low[p] = ord[p] = co++;
35+
vlis.push_back(p);
36+
par[p] = b;
37+
for (E e: g[p]) {
38+
if (rt and e.to == b) {
39+
rt = false;
40+
continue;
41+
}
42+
if (!used[e.to]) {
43+
dfs(g, e.to, p);
44+
low[p] = min(low[p], low[e.to]);
45+
} else {
46+
low[p] = min(low[p], ord[e.to]);
47+
}
48+
}
49+
}
50+
};

‎Cpp/Graph2/MaxFlow.h‎

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* Dinic法による最大流
3+
*
4+
* ほとんど蟻本そのまま
5+
* template引数のint Vは頂点数
6+
* Edgeにはrevが必要
7+
* ---
8+
* void add_edge(Graph<Edge> &g, int from, int to, int cap) {
9+
* g[from].push_back(Edge{to, cap, (int)g[to].size()});
10+
* g[to].push_back(Edge{from, 0, (int)g[from].size()-1});
11+
* }
12+
* ---
13+
*/
14+
template<class T> // Tは容量の型
15+
struct MaxFlow {
16+
const T INF = TEN(9);
17+
18+
int V;
19+
vector<int> level, iter;
20+
21+
//gを破壊するので注意
22+
template<class E>
23+
T exec(Graph<E> &g, int s, int t) {
24+
V = (int)g.size();
25+
level.resize(V);
26+
iter.resize(V);
27+
T flow = 0;
28+
while (true) {
29+
bfs(g, s);
30+
if (level[t] < 0) return flow;
31+
fill_n(iter.begin(), V, 0);
32+
while (true) {
33+
T f = dfs(g, s, t, INF);
34+
if (!f) break;
35+
flow += f;
36+
}
37+
}
38+
}
39+
40+
template<class E>
41+
void bfs(const Graph<E> &g, int s) {
42+
fill_n(level.begin(), V, -1);
43+
queue<int> que;
44+
level[s] = 0;
45+
que.push(s);
46+
while (!que.empty()) {
47+
int v = que.front(); que.pop();
48+
for (E e: g[v]) {
49+
if (e.cap <= 0) continue;
50+
if (level[e.to] < 0) {
51+
level[e.to] = level[v] + 1;
52+
que.push(e.to);
53+
}
54+
}
55+
}
56+
}
57+
58+
template<class E>
59+
T dfs(Graph<E> &g, int v, int t, T f) {
60+
if (v == t) return f;
61+
for (int &i = iter[v]; i < (int)g[v].size(); i++) {
62+
E &e = g[v][i];
63+
if (e.cap <= 0) continue;
64+
if (level[v] < level[e.to]) {
65+
T d = dfs(g, e.to, t, min(f, e.cap));
66+
if (d <= 0) continue;
67+
e.cap -= d;
68+
g[e.to][e.rev].cap += d;
69+
return d;
70+
}
71+
}
72+
return 0;
73+
}
74+
};

0 commit comments

Comments
 (0)