Skip to content

Commit 4ea2728

Browse files
committed
Dodano rozwiązanie zadania 'Osiedla' z XXVI OI
1 parent a37b95e commit 4ea2728

File tree

1 file changed

+65
-0
lines changed
  • rozwiazania/xxvi/etap2/dzien2/osi

1 file changed

+65
-0
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Rozwiązanie zadania 'Osiedla' z II etapu XXV OI.
2+
// Autor rozwiązania: Paweł Putra
3+
// Złożoność czasowa: O(n)
4+
// Złożoność pamięciowa: O(n)
5+
// Punkty: 100 (upsolve)
6+
7+
#include <bits/stdc++.h>
8+
9+
#include <vector>
10+
#include <iostream>
11+
#include <algorithm>
12+
#include <string>
13+
using namespace std;
14+
constexpr int MAXN = 1'000'005;
15+
16+
int spojne;
17+
string kierunki;
18+
vector<pair<int,int>> g[MAXN];
19+
20+
int vis[MAXN];
21+
int d[MAXN]; // d[v] = odległość v od korzenia (głębokość).
22+
int low[MAXN]; // low[v] = najniższa głębokość na jaką idzie krawędź powrotna z poddrzewa.
23+
24+
void dfs(int v, int p /* numer krawędzi którą przyszedłem */) {
25+
low[v] = d[v];
26+
vis[v] = 1;
27+
for (auto [w, i] : g[v]) {
28+
if (!vis[w]) {
29+
d[w] = d[v] + 1;
30+
kierunki[abs(i) - 1] = (i < 0 ? '>' : '<');
31+
dfs(w, abs(i));
32+
33+
low[v] = min(low[w], low[v]);
34+
}
35+
else if (abs(i) != p) {
36+
kierunki[abs(i) - 1] = (i < 0 ? '<' : '>');
37+
low[v] = min(low[v], d[w]);
38+
}
39+
}
40+
}
41+
42+
43+
int32_t main() {
44+
ios_base::sync_with_stdio(0);
45+
int n, m;
46+
cin >> n >> m;
47+
48+
kierunki = string(m, '<');
49+
for (int i = 1; i <= m; i++) {
50+
int a, b;
51+
cin >> a >> b;
52+
g[a].emplace_back(b, i);
53+
g[b].emplace_back(a, -i);
54+
}
55+
56+
for (int i = 1; i <= n; i++) {
57+
if (!vis[i])
58+
dfs(i, 0);
59+
60+
if (low[i] == d[i]) spojne++;
61+
}
62+
63+
cout << spojne << "\n";
64+
cout << kierunki << "\n";
65+
}

0 commit comments

Comments
 (0)