#include <stdio.h>
#include <algorithm>
#include <vector>
#include <numeric>
#include <assert.h>
using namespace std;
const int NMAX = 100010;
struct UF {
char r[NMAX];
int tata[NMAX];
UF() {
iota(tata, tata + NMAX, 0);
}
int find(int x) {
if (tata[tata[x]] != tata[x])
tata[x] = find(tata[x]);
return tata[x];
}
bool unite(int a, int b) {
a = find(a);
b = find(b);
if (a == b)
return 0;
if (r[a] < r[b])
swap(a, b);
if (r[a] == r[b]) {
r[a]++;
tata[b] = a;
}
else
tata[b] = a;
return 1;
}
} simple, strong;
namespace Tree {
int h[NMAX];
int father[NMAX];
int up[NMAX]; /// ultimul cu care stiu sigur ca m-am unit
vector <int> adia[NMAX]; /// suma ar trebui sa fie max NMAX :)
vector <pair <int, int>> single;
int n;
int _find(int nod) {
if (up[up[nod]] != up[nod])
up[nod] = _find(up[nod]);
return up[nod];
}
int find(int nod) {
up[nod] = _find(nod);
while (strong.find(up[nod]) == strong.find(father[up[nod]])) {
up[up[nod]] = father[up[nod]];
up[nod] = _find(nod);
}
return up[nod];
}
void make_strong(int a, int b) {
while (1) {
a = find(a);
b = find(b);
if (a == b)
return;
if (h[a] < h[b])
swap(a, b);
/// acum il unesc pe a cu tatal sau
assert(strong.find(a) != strong.find(father[a]));
assert(father[a] != 0);
strong.unite(a, father[a]);
up[a] = father[a];
}
}
void dfs(int nod, int tata) {
father[nod] = tata;
h[nod] = 1 + h[tata];
up[nod] = nod;
for (auto i : adia[nod])
if (i != tata)
dfs(i, nod);
}
void add_edge(int a, int b) {
if (simple.unite(a, b)) {
if (simple.r[a] < simple.r[b])
swap(a, b);
adia[a].push_back(b);
adia[b].push_back(a);
dfs(b, a);
}
else
make_strong(a, b);
}
void dfs_ans(int nod, int tata) {
for (auto i : adia[nod]) {
if (i == tata)
continue;
if (strong.find(i) != strong.find(nod))
single.push_back({ nod, i });
dfs_ans(i, nod);
}
}
void get_ans() {
for (int i = 1; i <= n; i++)
if (father[i] == 0)
dfs_ans(i, 0);
}
}
int main()
{
int n, m, a, b;
scanf("%d%d", &n, &m);
Tree::n = n;
iota(Tree::up, Tree::up + NMAX, 0);
while (m--) {
scanf("%d%d", &a, &b);
Tree::add_edge(a, b);
}
Tree::get_ans();
for (auto i : Tree::single)
printf("%d %d\n", i.first, i.second);
return 0;
}
Compilation message
pipes.cpp: In function 'int main()':
pipes.cpp:123:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf("%d%d", &n, &m);
~~~~~^~~~~~~~~~~~~~~~
pipes.cpp:128:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf("%d%d", &a, &b);
~~~~~^~~~~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
4 ms |
3840 KB |
Output is correct |
2 |
Correct |
4 ms |
3840 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
67 ms |
4024 KB |
Output is correct |
2 |
Correct |
31 ms |
4060 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
156 ms |
4024 KB |
Output is correct |
2 |
Correct |
124 ms |
3968 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
624 ms |
4500 KB |
Output is correct |
2 |
Correct |
335 ms |
4216 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
3067 ms |
5008 KB |
Output is correct |
2 |
Correct |
1933 ms |
5308 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
5085 ms |
6444 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
5016 ms |
6664 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
5040 ms |
7308 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
5032 ms |
7316 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
5071 ms |
7180 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |