問題概要
- 自己ループと二重辺を含まない\(N\)頂点\(M\)辺の無向連結グラフが与えられる。
- \(i\)番目の辺は頂点\(a_i\)と頂点\(b_i\)を結ぶ。
- グラフから辺を取り除いた時、グラフ全体が火連結になるような辺のことを橋と呼ぶ時、橋の本数を求めよ。
制約
- \(2 ≤ N ≤ 50\)
- \(N-1 ≤ M ≤ min(N(N-1)/2, 50)\)
- \(1 ≤ a_i < b_i ≤ N\)
- 与えられるグラフは自己ループと二重辺を含まない
- 与えられるグラフは連結である。
考えたこと
- 無向グラフのアルゴリズムには前回ABC54 C問題と同様に深さ優先探索を用いる(他にも幅優先探索、UnionFind, ワーシャル・フロイド法などが利用できるらしい)
- dfsでは、N個の頂点それぞれに訪問したかどうかを調べる目的で使用する。
#include<bits/stdc++.h>
using namespace std;
const int ilmit=50;
bool graph[limit][limit];
bool visited[limit];
int n, m;
int a[limit], b[limit];
bool dfs(int v) {
visited[v] = true;
for(int v2 = 0; v2 < n; ++v2) {
if(graph[v][v2] == false) continue;
if(visited[v2]) continue;
visited[v2] = true;
dfs(v2);
}
}
int main() {
cin >> n >> m;
for(int i = 0; i < m; ++i) {
cin >> a[i] >> b[i];
a[i]--, b[i]--;
graph[a[i]][b[i]] = graph[b[i]][a[i]] = true
}
int ans = 0;
for(int i = 0; i < m; ++i) {
graph[a[i]][b[i]] = graph[b[i]][a[i]] = false;
for(int j = 0; j < n; ++j) visited[j] = false;
dfs(0);
bool bridge = false;
for(int j = 0; j < n; ++j) if(visited[j] == false) bridge = true;
if(bridge) ans += 1;
graph[a[i]][b[i]] = graph[b[i]][a[i]] = true;
}
cout << ans << endl;
return 0;
}