#include <bits/stdc++.h>
#define int long long
typedef std::pair<int, int> pii;
const int N = 2e5 + 5, M = 6e5 + 5;
int n, m;
int dfn[N], low[N], tim;
int id[N], siz[N], bcc_cnt;
std::stack<int> st;
bool is_bridge[M];
std::vector<pii> answer;//记录边(转化成了有向边)
struct Edge
{
int to, next;
} edge[M];
int head[N], cnt;
void add_edge(int u, int v)
{
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt++;
}
void tarjan(int u, int fu)
{
dfn[u] = low[u] = ++tim;
st.push(u);
for (int i = head[u]; i != -1; i = edge[i].next)
{
int j = edge[i].to;
if (!dfn[j])
{
tarjan(j, i);
answer.push_back({u, j});
low[u] = std::min(low[u], low[j]);
if (dfn[u] < low[j])
{
is_bridge[i] = is_bridge[i ^ 1] = true;
}
}
else if (i != (fu ^ 1))
{
low[u] = std::min(low[u], dfn[j]);
if (dfn[j] < dfn[u])
{
answer.push_back({u, j});
}
}
}
if (dfn[u] == low[u])
{
++bcc_cnt;
int k;
do
{
k = st.top();
st.pop();
} while (k != u);
}
}
void solve()
{
memset(head, -1, sizeof head);
std::cin >> n >> m;
for (int i = 1, a, b; i <= m; i++)
{
std::cin >> a >> b;
add_edge(a, b);
add_edge(b, a);
}
tarjan(1, -1);
if (bcc_cnt > 1)
{
std::cout << 0 << std::endl;
return;
}
for (pii val : answer)
{
std::cout << val.first << " " << val.second << std::endl;
}
}
signed main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0), std::cout.tie(0);
int T = 1;
// std::cin >> T;
for (int i = 1; i <= T; i++)
{
solve();
}
return 0;
}
Tarjan边双连通分量【模板】
最新推荐文章于 2024-10-15 19:28:18 发布