treeman667
some guy stole my name 😡
- Graph
intro
representations
basic traversal
sssp, apsp
binary lifting/functional graph
mst
scc/k-sat
euler tour
hamiltonian path
flow
1
4
3
6
5
2
1
4
6
5
3
2
1
4
3
6
5
2
同構性
這兩張圖是一樣的
1
4
6
5
3
2
1
4
3
6
5
2
1
4
6
5
3
2
點
1
4
6
5
3
2
邊
1
4
6
5
3
2
路徑
有起點跟終點的一條路
1
4
6
5
3
2
3
6
7
2
1
邊權
1
4
6
5
3
2
3
6
7
2
1
7
點權
1
4
6
5
3
2
連通塊
Component 1
Component 2
1
4
6
5
3
2
環
1
4
6
5
3
2
有向圖
1
4
6
5
3
2
有向無環圖 簡稱 DAG
1
4
6
5
3
2
Indeg: 1
Outdeg: 1
Indeg: 0
Outdeg: 1
Indeg: 0
Outdeg: 1
Indeg: 0
Outdeg: 0
Indeg: 0
Outdeg: 2
Indeg: 4
Outdeg: 0
度數
Indeg - 入度
Outdeg - 出度
1
4
6
5
3
2
簡單性質
1
4
6
5
3
2
3
6
7
2
1
| {1, 2, 6} | {1, 4, 3} | {1, 5, 7} | {2, 3, 1} | {3, 1, 2} |
|---|
#include <vector>
template<typename T>
struct edge
{
int u, v;
T data;
};
std::vector<edge<int>> edge_list;
# PRESENTING CODE
1
4
6
5
3
2
3
6
7
2
1
| 2, 6 | 4, 3 | 5, 7 |
|---|
| 3, 1 |
|---|
| 1, 2 |
|---|
| 1 |
|---|
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
#include <vector>
template<typename T>
struct edp
{
int ed;
T data;
};
std::vector<edp<int>> al[MAXN];
# PRESENTING CODE
1
4
6
5
3
2
3
6
7
2
1
| 1 | 2 | 3 | 4 | 5 | 6 | |
|---|---|---|---|---|---|---|
| 1 | 0 | 6 | ∞ | 3 | 7 | ∞ |
| 2 | ∞ | 0 | 1 | ∞ | ∞ | ∞ |
| 3 | 2 | ∞ | 0 | ∞ | ∞ | ∞ |
| 4 | ∞ | ∞ | ∞ | 0 | ∞ | ∞ |
| 5 | ∞ | ∞ | ∞ | ∞ | 0 | ∞ |
| 6 | ∞ | ∞ | ∞ | ∞ | ∞ | 0 |
#include <vector>
std::vector<vector<int>> am;
# PRESENTING CODE
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
void dfs(int u)
{
visited[u] = 1
for (int v : al[u])
if (!visited[v])
dfs(v);
}
# PRESENTING CODE
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
3
6
5
2
queue<int> bfs;
bfs.push(start);
while (!bfs.empty())
{
int u = bfs.front();
bfs.pop();
visited[u] = 1;
for (int v : al[u])
if (!visited[v])
bfs.push(v);
}
# PRESENTING CODE
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
string s;
bool visited[7][7];
int ans = 0;
void dfs(int i, int j, int steps = 0)
{
if (i == 6 && j == 0)
{
if (steps != 48)
return;
++ans;
}
if ((i == 0 || visited[i - 1][j]) && (i == 6 || visited[i + 1][j]) && j > 0 && j < 6 && !visited[i][j - 1] && !visited[i][j + 1])
{
visited[i][j] = false;
return;
}
if ((j == 0 || visited[i][j - 1]) && (j == 6 || visited[i][j + 1]) && i > 0 && i < 6 && !visited[i - 1][j] && !visited[i + 1][j])
{
visited[i][j] = false;
return;
}
visited[i][j] = true;
if (s[steps] == '?' || s[steps] == 'U')
if ( i && !visited[i-1][j])
dfs(i-1, j, steps + 1);
if (s[steps] == '?' || s[steps] == 'D')
if ( i < 6 && !visited[i+1][j])
dfs(i+1, j, steps + 1);
if (s[steps] == '?' || s[steps] == 'L')
if ( j && !visited[i][j-1])
dfs(i, j-1, steps + 1);
if (s[steps] == '?' || s[steps] == 'R')
if ( j < 6 && !visited[i][j+1])
dfs(i, j+1, steps + 1);
visited[i][j] = false;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> s;
dfs(0, 0);
cout << ans;
}
# PRESENTING CODE
s
t
s
t
s
t
s
t
s
t
while (--n)
{
for (auto [a, b, len] : el)
if (dist[a] + len < dist[b])
dist[b] = dist[a] + len
if (dist[b] + len < dist[a])
dist[a] = dist[b] + len
}
# PRESENTING CODE
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq
vector<int> dist(n, 0x7fffffff)
pq.push(0, start)
while (!pq.empty)
w = pq.top().first, v = pq.top().second
pq.pop()
if (dist[v] != w)
continue
for (a, b : al[v])
if (dist[v] + a < dist[b])
dist[b] = dist[v] + a
pq.push({dist[b], b});
# PRESENTING CODE
vector<vector<int>> dp(MAXN, vector<int>(MAXN, 0x7fffffff))
for (int i=1; i <= n; i++)
dp[i][i] = 0
while (m--)
u, v, w
cin >> u >> v >> w
dp[u][v] = dp[v][u] = w
for (int k = 1; k <= n; k++)
for (int i=1; i <= n; i++)
for (int j = 1; j <= n; j++)
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j])
# PRESENTING CODE
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1e18 + 114514;
int main()
{
int n, m; cin >> n >> m;
vector<vector<pair<int, int>>> al(n + 1);
while (m--)
{
int a, b, c; cin >> a >> b >> c;
al[a].push_back({b, c});
}
vector<array<ll, 2>> dist(n+1, array<ll, 2>({INF, INF}));
dist[1][0] = 0; dist[1][1] = 0;
priority_queue<tuple<ll, int, bool>, vector<tuple<ll, int, bool>>, greater<>> pq;
pq.push({0, 1, 0}); pq.push({0, 1, 1});
while (!pq.empty())
{
auto [cost, cur_node, used] = pq.top(); pq.pop();
if (dist[cur_node][used] != cost) continue;
for (auto &[v, w] : al[cur_node])
{
if (dist[v][0] > dist[cur_node][0] + w)
{
dist[v][0] = dist[cur_node][0] + w;
pq.push({dist[v][0], v, 0});
}
if (dist[v][1] > dist[cur_node][0] + w/2)
{
dist[v][1] = dist[cur_node][0] + w/2;
pq.push({dist[v][1], v, 1});
}
if (dist[v][1] > dist[cur_node][1] + w)
{
dist[v][1] = dist[cur_node][1] + w;
pq.push({dist[v][1], v, 1});
}
}
}
cout << min(dist[n][0], dist[n][1]);
}
# PRESENTING CODE
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, m;
cin >> n >> m;
vector<int> indeg(n+1);
vector<vector<int>> al(n+1);
while (m--)
{
int a, b; cin >> a >> b;
al[a].push_back(b);
indeg[b]++;
}
queue<int> bfs;
for (int i=1; i <= n; i++)
if (!indeg[i]) bfs.push(i);
vector<int> order;
while (!bfs.empty())
{
int u = bfs.front();
bfs.pop();
order.push_back(u);
for (int v : al[u])
{
--indeg[v];
if (!indeg[v]) bfs.push(v);
}
}
}
# PRESENTING CODE
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 215;
bool visited[MAXN];
vector<int> al[MAXN];
vector<int> order;
void dfs(int u)
{
visited[u] = 1;
for (int v : al[u])
if (!visited[v])
dfs(v);
order.push_back(u);
}
int main()
{
int n, m;
cin >> n >> m;
while (m--)
{
int a, b;
cin >> a >> b;
al[a].push_back(b);
}
dfs(1);
reverse(order.begin(), order.end());
}
# PRESENTING CODE
1
3
6
6
5
2
4
4
4
7
0
8
9
1
3
6
6
5
2
4
4
4
7
0
8
9
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 10;
int n, m;
static bool visited[MAXN];
vector<vector<int>> al(MAXN);
vector<vector<int>> ral(MAXN);
stack<int> ft;
void dfs(int u)
{
for (int v : al[u])
{
if (!visited[v])
{
visited[v] = 1;
dfs(v);
}
}
ft.push(u);
}
void rdfs(int u, int &id)
{
for (int v : ral[u])
{
if (visited[v]) continue;
visited[v] = 1;
p[v] = id;
rdfs(v, id);
}
}
int main()
{
cin >> n >> m;
while (m--)
{
int a, b; cin >> a >> b;
al[a].push_back(b);
ral[b].push_back(a);
}
for (int i=1; i <= n; i++)
if (!visited[i])
{
visited[i] = 1;
dfs(i);
}
memset(visited, false, sizeof(visited));
int cnt = 0;
while (!ft.empty())
{
while (!ft.empty() && visited[ft.top()] ) ft.pop();
if (ft.empty()) break;
cnt++;
int u = ft.top(); ft.pop();
visited[u] = 1;
p[u] = cnt;
rdfs(u, cnt);
}
}
# PRESENTING CODE
1
4
6
5
3
2
1
4
3
6
5
2
1
4
3
6
5
2
1
4
6
5
3
2
1
6
7
5
4
9
8
10
2
3
1
4
3
6
5
2
1
5
4
2
3
MST
*每一步都會找到邊(u, v) 且它會符合mst的定義 則 (u, v) 是一個 safe edge
1. 隨便抓一個點
1. 隨便抓一個點
2. 預設到起點花費 = 0
1. 隨便抓一個點
2. 預設到起點花費 = 0
3. 把起點丟到一個 min heap
1. 隨便抓一個點
2. 預設到起點花費 = 0
3. 把起點丟到一個 min heap
4. 把可以到的所有點和其距離加到heap裡面
1. 隨便抓一個點
2. 預設到起點花費 = 0
3. 把起點丟到一個 min heap
4. 把可以到的所有點和其距離加到heap裡面
5. 選一個距離最小且沒有加進來的點
1. 隨便抓一個點
2. 預設到起點花費 = 0
3. 把起點丟到一個 min heap
4. 把可以到的所有點和其距離加到heap裡面
5. 選一個距離最小且沒有加進來的點
6. 更新可以到達的點的距離
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int n, m;
int main()
{
cin >> n >> m;
vector<vector<pair<int, int>>> al(n+1);
while (m--)
{
int a, b, c; cin >> a >> b >> c;
al[a].push_back({b, c});
al[b].push_back({a, c});
}
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;
pq.push({0, 1});
vector<bool> visited(n+1, false);
ll total = 0;
while (!pq.empty())
{
auto [w, u] = pq.top(); pq.pop();
if (visited[u])
continue;
visited[u] = 1;
total += w;
for (auto &[v, d] : al[u])
if (!visited[v])
pq.push({d, v});
}
cout << total;
}
# PRESENTING CODE
#include <bits/stdc++.h>
using namespace std;
int n, m;
const int MAXN = 2e5 +215;
int main()
{
cin.tie(nullptr)->sync_with_stdio(false);
cin >> n >> m;
while (m--)
{
int a, b, c;
cin >> a >> b >> c;
saves.push_back({a, b, c});
}
sort(saves.begin(), saves.end(), [&](auto t1, auto t2)
{
auto [a, b, c] = t1;
auto [d, e, f] = t2;
return c < f;
});
long long ans = 0;
int tn = 0;
for (auto [u, v, c] : saves)
if (fd(u) != fd(v))
unions(u, v), ans += c, ++tn;
}
# PRESENTING CODE
int find_set(int v)
{
if (v == p[v])
return v;
return find_set(p[v]);
}
void union_sets(int a, int b)
{
a = find_set(a);
b = find_set(b);
if (a != b)
p[b] = a;
}
# PRESENTING CODE
bool union_set(int a, int b)
{
a = find_set(a);
b = find_set(b);
if (a == b) return 0;
if (sz[a] < sz[b]) swap(a, b);
parent[b] = a;
sz[a] += sz[b];
return 1;
}
# PRESENTING CODE
int find_set(int v)
{
if (v == p[v])
return v;
return p[v] = find_set(p[v]);
}
# PRESENTING CODE
Seven Bridges of Königsberg
謝謝roychuang的教並回答 讓我不再納悶
By treeman667