QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#839333 | #873. Königsberg Bridges | ohwphil | AC ✓ | 1141ms | 391628kb | C++17 | 6.1kb | 2025-01-01 17:08:41 | 2025-01-01 17:08:41 |
Judging History
answer
#include <bits/stdc++.h>
#include <array>
using namespace std;
typedef long long ll;
// DFS Tree
// Finds bridges, articulation points, and biconnected components
struct DFSTree {
// size of graph
int N;
vector<vector<int>> adj, tree_children, back_edges;
vector<int> tree_parent;
vector<int> depth, dp;
vector<pair<int, int>> bridges;
vector<int> articulation_points;
vector<vector<pair<int, int>>> biconnected_components;
stack<pair<int, int>> edge_stack;
DFSTree() { DFSTree(0); }
DFSTree(int _N) : N(_N), adj(_N + 1), tree_children(_N + 1), back_edges(_N + 1), tree_parent(_N + 1, -1), depth(_N + 1, -1), dp(_N + 1) {}
void add_edge(int u, int v) {
adj[u].push_back(v);
adj[v].push_back(u);
}
void dfs(int curr_node, int curr_depth = 0) {
depth[curr_node] = curr_depth;
int cnt = 0;
for (int next_node : adj[curr_node]) {
if (next_node == tree_parent[curr_node]) {
continue;
}
if (depth[next_node] == -1) {
edge_stack.push(make_pair(min(curr_node, next_node), max(curr_node, next_node)));
tree_children[curr_node].push_back(next_node);
tree_parent[next_node] = curr_node;
int curr_dp = dp[curr_node];
dfs(next_node, curr_depth + 1);
dp[curr_node] += dp[next_node];
if (dp[curr_node] == curr_dp) {
++cnt;
// separate biconnected component
vector<pair<int, int>> component;
auto reference_pair = make_pair(min(curr_node, next_node), max(curr_node, next_node));
while (true) {
auto edge = edge_stack.top();
edge_stack.pop();
component.push_back(edge);
if (edge == reference_pair) {
break;
}
}
biconnected_components.push_back(component);
}
}
else if (depth[next_node] < depth[curr_node]) {
edge_stack.push(make_pair(min(curr_node, next_node), max(curr_node, next_node)));
back_edges[curr_node].push_back(next_node);
++dp[next_node];
--dp[curr_node];
}
}
if (tree_parent[curr_node] != -1 && dp[curr_node] == 0) {
bridges.push_back({min(curr_node, tree_parent[curr_node]), max(curr_node, tree_parent[curr_node])});
}
if ((tree_parent[curr_node] == -1 && cnt >= 2) || (tree_parent[curr_node] != -1 && cnt >= 1)) {
articulation_points.push_back(curr_node);
}
}
void compute() {
for (int i = 1; i <= N; i++) {
if (depth[i] == -1) {
dfs(i, 0);
}
}
sort(bridges.begin(), bridges.end());
sort(articulation_points.begin(), articulation_points.end());
}
};
// Disjoint set union
struct DSU {
// size of graph
int N;
vector<int> rank;
DSU() { DSU(0); }
DSU(int _N) : N(_N), rank(_N + 1, -1) {}
int get_parent(int node) {
if (rank[node] < 0) {
return node;
}
return rank[node] = get_parent(rank[node]);
}
void merge(int node1, int node2) {
node1 = get_parent(node1);
node2 = get_parent(node2);
if (node1 == node2) return;
if (-rank[node1] < -rank[node2]) swap(node1, node2);
rank[node1] += rank[node2];
rank[node2] = node1;
}
};
int N, M;
DFSTree tree;
DSU dsu;
vector<int> bridge_dp;
set<pair<int, int>> multiple_edges;
map<pair<int, int>, int> counter;
vector<int> visited;
int ans;
int dfs_dp(int node, int& curr_ans) {
// bridge_dp[node] = (tree.tree_parent[node] != -1 && tree.dp[node] == 0);
// if (tree.tree_parent[node] != -1 && multiple_edges.find({min(node, tree.tree_parent[node]), max(node, tree.tree_parent[node])}) != multiple_edges.end()) {
// bridge_dp[node] = 0;
// }
visited[node] = true;
vector<int> values;
for (auto child : tree.tree_children[node]) {
int curr_val = dfs_dp(child, curr_ans);
if (multiple_edges.find({min(node, child), max(node, child)}) == multiple_edges.end() && tree.dp[child] == 0) {
++curr_val;
}
values.push_back(curr_val);
}
sort(values.begin(), values.end());
if (values.size() == 0) {
return 0;
}
if (values.size() == 1) {
curr_ans = max(values[0], curr_ans);
}
if (values.size() >= 2) {
curr_ans = max(values[values.size() - 2] + values[values.size() - 1], curr_ans);
}
return values[values.size() - 1];
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> N >> M;
bridge_dp.resize(N + 1);
visited.resize(N + 1);
dsu = DSU(N);
tree = DFSTree(N);
for (int i = 0; i < M; ++i) {
int u, v;
cin >> u >> v;
if (u == v) continue;
++u; ++v;
if (u > v) swap(u, v);
// tree.add_edge(u, v);
// edge_sets.insert({u, v});
++counter[{u, v}];
if (counter[{u, v}] == 2) {
multiple_edges.insert({u, v});
}
}
for (auto [p, c] : counter) {
auto [u, v] = p;
tree.add_edge(u, v);
dsu.merge(u, v);
}
vector<int> parents;
for (int i = 1; i <= N; ++i) {
parents.push_back(dsu.get_parent(i));
}
sort(parents.begin(), parents.end());
parents.erase(unique(parents.begin(), parents.end()), parents.end());
tree.compute();
for (int i = 1; i <= N; ++i) {
if (!visited[i]) {
int curr_ans = 0;
dfs_dp(i, curr_ans);
ans += curr_ans;
}
}
ans += parents.size() - 1;
cout << ans << "\n";
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3616kb
input:
4 3 0 1 1 2 2 0
output:
1
result:
ok 1 number(s): "1"
Test #2:
score: 0
Accepted
time: 0ms
memory: 3560kb
input:
4 2 0 1 1 2
output:
3
result:
ok 1 number(s): "3"
Test #3:
score: 0
Accepted
time: 609ms
memory: 169932kb
input:
266912 867557 0 31522 0 174162 0 4209 1 58647 1 5722 1 24762 1 258525 1 148028 1 72989 1 170812 1 260494 1 86533 1 212481 2 143457 2 47080 2 72841 2 113512 2 64754 2 231454 3 220536 3 97144 3 183508 3 177546 3 149060 3 140197 3 87427 3 169096 4 132318 4 67337 4 23014 4 34254 4 11851 4 12558 4 49756 ...
output:
380
result:
ok 1 number(s): "380"
Test #4:
score: 0
Accepted
time: 454ms
memory: 126744kb
input:
92162 903746 0 78341 0 30101 0 86910 0 71281 0 66038 0 58991 0 27261 0 12794 0 44202 0 27063 0 8617 0 1463 0 48097 0 24219 0 51184 0 42335 0 20179 0 79826 0 29670 0 121 0 80004 0 22547 0 54055 0 80647 0 20967 0 7230 0 20852 0 67815 0 63277 0 61650 1 24614 1 60787 1 78668 1 73795 1 36239 1 90410 1 71...
output:
0
result:
ok 1 number(s): "0"
Test #5:
score: 0
Accepted
time: 23ms
memory: 98156kb
input:
946158 0
output:
946157
result:
ok 1 number(s): "946157"
Test #6:
score: 0
Accepted
time: 47ms
memory: 76412kb
input:
717331 671 277 661428 388 696195 2457 576086 2926 555369 2959 191594 4142 432000 4312 309773 4858 471165 4886 682026 5569 403920 5620 470329 6027 546706 6049 179350 6596 471181 6792 416677 7466 628061 7648 378219 7650 560432 7660 55602 7973 18975 8076 121285 8123 172484 8325 202734 8570 501604 8904 ...
output:
717330
result:
ok 1 number(s): "717330"
Test #7:
score: 0
Accepted
time: 1141ms
memory: 301380kb
input:
1000000 1000000 0 168067 0 116972 1 776624 1 327773 1 145060 2 14506 2 181311 2 431159 2 652430 3 173884 4 394795 4 172555 5 494172 5 945490 7 595196 7 593371 7 358866 8 860794 9 598459 10 505821 10 41753 10 880384 11 74592 11 715116 11 659129 12 977041 12 807365 12 952349 13 844571 13 154379 15 185...
output:
200542
result:
ok 1 number(s): "200542"
Test #8:
score: 0
Accepted
time: 1132ms
memory: 303656kb
input:
1000000 999999 1 412610 2 712889 2 254970 2 803563 3 678225 6 294090 6 662272 7 593625 7 444343 7 348966 7 168525 8 273575 8 486405 9 644268 9 321394 9 223587 11 719799 11 547678 11 742807 11 332536 12 260338 13 995176 14 234723 14 785909 15 406384 15 636469 16 388652 16 528991 17 741822 18 78605 19...
output:
201011
result:
ok 1 number(s): "201011"
Test #9:
score: 0
Accepted
time: 62ms
memory: 104088kb
input:
1000000 8936 62 728171 75 810657 186 344905 204 186449 253 441452 271 371090 292 948549 306 595932 315 901739 390 621170 396 287021 473 437138 494 530383 513 588605 527 23089 531 768891 567 189841 600 335182 693 723411 731 521138 745 696157 877 168905 925 902019 997 668395 1025 968824 1152 56167 119...
output:
999999
result:
ok 1 number(s): "999999"
Test #10:
score: 0
Accepted
time: 597ms
memory: 273680kb
input:
688670 688669 0 1 1 2 1 3 1 4 3 5 4 10 5 6 6 7 7 8 8 9 9 11 9 12 11 13 11 14 14 15 14 17 15 16 16 18 16 19 18 24 18 26 19 20 19 22 20 21 21 23 21 27 23 25 23 28 25 29 25 30 29 31 29 36 31 32 31 34 32 33 33 35 34 39 35 37 37 38 37 41 38 40 40 42 40 43 42 44 44 45 44 48 45 46 46 47 46 49 46 51 47 50 4...
output:
398561
result:
ok 1 number(s): "398561"
Test #11:
score: 0
Accepted
time: 895ms
memory: 391628kb
input:
1000000 999999 0 1 0 2 1 3 1 7 2 5 3 4 4 6 6 8 7 9 8 10 8 11 8 12 12 13 13 14 14 15 15 16 16 17 16 18 16 19 17 22 18 20 20 21 21 23 23 24 24 25 25 26 25 27 25 28 26 31 27 29 29 30 31 32 32 33 32 40 33 34 34 35 34 39 35 36 36 37 37 38 38 41 41 42 41 43 42 44 44 45 44 46 45 47 47 48 48 49 48 51 49 50 ...
output:
578343
result:
ok 1 number(s): "578343"