Mô tả bài toán
Cho đồ thị vô hướng, không đa cung, không khuyên, n đỉnh, m cạnh. Cạnh cầu (bridge) là cạnh mà nếu xóa sẽ làm đồ thị không liên thông. Đếm số cạnh cầu.
Ví dụ
n=5,m=6, edges={{1,2},{1,3},{2,3},{2,4},{2,5},{3,5}}. Đầu ra: 1 (chỉ cạnh {2,4} là cầu).
Thuật toán (Tarjan tìm cầu)
- DFS từ mỗi đỉnh chưa thăm, giữ
vk(thời gian khám phá) vàl(low-link). - Khi duyệt cạnh
v→x(x chưa thăm): đệ quy, cập nhậtl[v] = min(l[v], l[x]). Nếul[x] > vk[v]thì cạnh(v,x)là cầu. - Nếu
xđã thăm và không phải cha:l[v] = min(l[v], vk[x]). - Đếm số cặp
(i,j)cóbridge[i][j]==1.
Đoạn mã C++
#include <bits/stdc++.h>
using namespace std;
const int mSize = 100;
vector<int> G[mSize];
vector<vector<int>> bridge(mSize, vector<int>(mSize));
vector<int> visited(mSize);
vector<int> vk(mSize,-1), low(mSize,-1);
vector<pair<int,int>> edges;
int n,m,t;
void dfs(int v, int p=-1) {
visited[v]=1;
vk[v]=low[v]=t++;
for(int x: G[v]) {
if(x==p) continue;
if(visited[x]) low[v]=min(low[v], vk[x]);
else {
dfs(x,v);
low[v]=min(low[v], low[x]);
if(low[x] > vk[v]) bridge[v][x]=1;
}
}
}
void bridgeSearch() {
t=0;
for(int i=1;i<=n;i++) if(!visited[i]) dfs(i);
}
int solve() {
for(int i=0;i
Đầu vào / Đầu ra
Input: 5, 6, {{1,2},{1,3},{2,3},{2,4},{2,5},{3,5}}
Output: 1