#include <bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>
//#pragma GCC optimize ("O3")
//#pragma GCC target ("sse4")
#pragma GCC target ("avx,tune=native")
//Use above if bruteforcing with lots of small operations. Or just use it anytime, there's no downside. AVX is better slightly
/*
TASK: hidden
LANG: C++11
*/
using namespace std;
//using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int, int> pair2;
typedef pair<int, pair<int, int> > pair3;
typedef pair<int, pair<int, pair<int, int> > > pair4;
#define MAXN 100013
#define INF 1000000000000000000LL
#define mp make_pair
#define add push_back
#define remove pop
int n, m;
vector<int> adj[MAXN];
//vector<pair<int, int>> answer;
int depth[MAXN], lowestAdjDepth[MAXN];
struct UnionFind {
int * id;
int * size;
int count;
UnionFind(int sz) {
id = new int[sz];
size = new int[sz];
count = sz;
for (int i = 0; i < sz; i++) {
size[i] = 1;
id[i] = i;
}
}
UnionFind(){}
bool sameset(int p, int q) {
return find(p) == find(q);
}
int find(int p) {
if (p != id[p]) {
id[p] = find(id[p]);
}
return id[p];
}
void merge(int p, int q) {
int rootp = find(p);
int rootq = find(q);
if (rootp == rootq) return;
if (size[rootp] < size[rootq]) {
id[rootp] = rootq;
size[rootq] += size[rootp];
} else {
id[rootq] = rootp;
size[rootp] += size[rootq];
}
count--;
}
} uf[2];
//returns subtree size
void solve(int current, int parent) {
assert(depth[current] >= 1);
lowestAdjDepth[current] = depth[current];
//cout << "solving " << current << " lad dis " << lowestAdjDepth[current] << endl;
bool t = false;
for (int next : adj[current]) {
if (next == parent && !t) {t = true; continue;}
if (depth[next] >= 1) {
lowestAdjDepth[current] = min(lowestAdjDepth[current], depth[next]);
} else {
//unvisited, let's go visit!
depth[next] = depth[current] + 1;
solve(next, current);
lowestAdjDepth[current] = min(lowestAdjDepth[current], lowestAdjDepth[next]);
//cout << "current is " << current << " lad next is " << lowestAdjDepth[next] << " depth current is " << depth[current] << endl;
if (lowestAdjDepth[next] > depth[current]) {
//the next node is in a biconnected component unaffected by current node
//answer.add(mp(current, next));
cout << current + 1 << ' ' << next + 1 << endl;
}
}
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin >> n >> m;
uf[0] = UnionFind(n);
uf[1] = UnionFind(n);
for (int i = 0; i < m; i++) {
int a, b;
cin >> a >> b;
a--;b--;
if (!uf[0].sameset(a, b)) {
adj[a].add(b);
adj[b].add(a);
uf[0].merge(a, b);
} else if (!uf[1].sameset(a, b)) {
adj[a].add(b);
adj[b].add(a);
uf[1].merge(a, b);
}
}
for (int i = 0; i < n; i++) {
if (depth[i] == 0) {
depth[i] = 1;
solve(i, -1);
}
}
/*
for (auto t : answer) {
cout << t.first + 1 << ' ' << t.second + 1<< endl;
}*/
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
3 ms |
2688 KB |
Output is correct |
2 |
Correct |
4 ms |
2688 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
13 ms |
3200 KB |
Output is correct |
2 |
Correct |
8 ms |
3072 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
104 ms |
3052 KB |
Output is correct |
2 |
Correct |
100 ms |
2936 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
162 ms |
3912 KB |
Output is correct |
2 |
Correct |
191 ms |
3392 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
301 ms |
5616 KB |
Output is correct |
2 |
Correct |
247 ms |
5292 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
401 ms |
11272 KB |
Output is correct |
2 |
Correct |
392 ms |
7796 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
648 ms |
12520 KB |
Output is correct |
2 |
Correct |
592 ms |
9612 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
833 ms |
14704 KB |
Output is correct |
2 |
Correct |
798 ms |
9820 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1055 ms |
14832 KB |
Output is correct |
2 |
Correct |
1066 ms |
9860 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1294 ms |
14292 KB |
Output is correct |
2 |
Correct |
1182 ms |
11484 KB |
Output is correct |