내가 보려고 모은 PS용 code snippets
Updated:
Categories: algonote, algorithm
Tags: study
최단거리 알고리즘
Dijkstra
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from heapq import heappop, heappush
adj = [[] for _ in range(N)]
for _ in range(M):
s, e, c = map(int, input().split())
adj[s].append((c, e))
INF = int(1e9)+1
dijk = [(0, st)]
dist = [INF]*N
dist[st] = 0
while dijk:
c, v = heappop(dijk)
if dist[v] != c: continue
for nc, nv in adj[v]:
nc += c
if dist[nv] <= nc: continue
heappush(dijk, (nc, nv))
dist[nv] = nc
print(dist[en])
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
typedef pair<int, int> PII;
const int INF = 1e9 + 1;
void dijk(vector<PII>* adj, int* dist, int S) {
priority_queue<PII, vector<PII>, greater<>> pQ;
pQ.push({0, S});
dist[S] = 0;
while (pQ.size()) {
int c, v;
tie(c, v) = pQ.top();
pQ.pop();
if (dist[v] != c) continue;
for (PII p : adj[v]) {
int nc, nv;
tie(nc, nv) = p;
nc += c;
if (dist[nv] <= nc) continue;
pQ.push({nc, nv});
dist[nv] = nc;
}
}
}
Bellman-Ford
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const int INF = 1e9 + 1;
fill(dist, dist + 502, INF);
dist[1] = 0;
for (int i = 0; i < N; i++) {
for (int st = 1; st <= N; st++) {
for (auto &p : adj[st]) {
int c, en;
tie(c, en) = p;
if (dist[st] == INF || dist[en] <= dist[st] + c) continue;
if (i == N - 1) minusCycle++;
dist[en] = dist[st] + c;
}
}
}
Floyd-Warshall
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
const int INF = 1e9 + 2;
for (int i = 0; i < 102; i++)
fill(floyd[i], floyd[i] + 102, INF);
for (int i = 0; i <= N; i++) floyd[i][i] = 0;
for (int k = 1; k <= N; k++) {
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
int bypass = floyd[i][k] + floyd[k][j];
floyd[i][j] = min(floyd[i][j], bypass);
}
}
}
SPFA
(TODO)
Segment Tree
(TODO)
Strongly Connected Component
Kosaraju
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <bits/stdc++.h>
// 2-SAT-4
// https://www.acmicpc.net/problem/11281
using namespace std;
const int MXV = 20'020;
vector<int> adj[MXV], radj[MXV], vis(MXV);
int sccid, z, x, N, M;
stack<int> stk;
// 1 -> 1, -1 -> 2, ...
int neg(int v) {
return v & 1 ? v + 1 : v - 1;
}
int iabs(int v) {
return 0 < v ? v * 2 - 1 : -2 * v;
}
void dfs(int v) {
vis[v] = 1;
for (auto nv : adj[v]) {
if (vis[nv]) continue;
dfs(nv);
}
stk.push(v);
}
void rdfs(int v) {
vis[v] = sccid;
for (auto nv : radj[v]) {
if (vis[nv]) continue;
rdfs(nv);
}
}
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N >> M;
for (int i = 0; i < M; i++) {
cin >> z >> x;
z = iabs(z);
x = iabs(x);
adj[neg(z)].push_back(x);
adj[neg(x)].push_back(z);
radj[z].push_back(neg(x));
radj[x].push_back(neg(z));
}
for (int i = 1; i <= 2 * N; i++)
if (!vis[i]) dfs(i);
fill(vis.begin(), vis.end(), 0);
while (!stk.empty()) {
x = stk.top();
stk.pop();
if (vis[x]) continue;
sccid++;
rdfs(x);
}
vector<pair<int, int>> scc_node;
int ans1 = 1;
for (int i = 1; i <= N; i++)
if (vis[2 * i] == vis[2 * i - 1]) ans1 = 0;
cout << ans1 << "\n";
if (!ans1) return 0;
vector<int> ans2(N + 1, -1);
for (int i = 1; i <= 2 * N; i++)
scc_node.push_back({vis[i], i});
sort(scc_node.begin(), scc_node.end());
for (auto [sid, n] : scc_node) {
x = (n + 1) / 2;
// positive면 0을, negative면 1을 담는다
if (ans2[x] == -1)
ans2[x] = 1 - (n & 1);
}
for (int i = 1; i <= N; i++) cout << ans2[i] << " ";
}
Tarjan
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
bool done[MXN];
stack<int> scc_stk;
vector<int> adj[MXN];
int N, M, u, v, dfs_id, dfs_no[MXN], scc_id, scc_no[MXN];
int tarjan(int node) {
scc_stk.push(node);
int result = dfs_no[node] = dfs_id++;
for (int next_node : adj[node])
if (!done[next_node])
result = min(result,
(dfs_no[next_node]) ? dfs_no[next_node] : tarjan(next_node));
if (result == dfs_no[node]) {
while (1) {
v = scc_stk.top();
scc_stk.pop();
scc_no[v] = scc_id;
done[v] = true;
if (v == node) break;
}
scc_id++;
}
return result;
}
Python
- recursion limit 주의
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
setrecursionlimit(10 ** 9)
dfs_id, scc_id = 1, 1
adj, done, dfs_no, scc_no, scc_stk = [], [], [], [], []
def tarjan(node):
global dfs_id, scc_id
scc_stk.append(node)
dfs_no[node] = (result := (dfs_id := dfs_id + 1))
for next_node in adj[node]:
if not done[next_node]:
result = min(result, dfs_no[next_node] or tarjan(next_node))
if result == dfs_no[node]:
while 1:
v = scc_stk.pop()
scc_no[v] = scc_id
done[v] = True
if v == node:
break
scc_id += 1
return result
ETC
Union-find
C++
1
2
3
4
5
6
7
8
9
10
int grpNo[202];
int find(int v) {
if (grpNo[v] == v) return v;
grpNo[v] = find(grpNo[v]);
return grpNo[v];
}
void unite(int a, int b) {
if (a < b) swap(a, b);
grpNo[find(a)] = find(b);
}
Leave a comment