Tarjan解无向图的割点和桥,参考白书。
/* 4587 */
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std; #define MAXN 5005 vector<int> vc[MAXN];
int dfs_clock;
int cnt[MAXN];
int pre[MAXN];
int n, m, cur; int Tarjan(int u, int fa) {
int i, j, k, v;
int lowu, lowv;
int child = ; lowu = pre[u] = ++dfs_clock;
for (i=; i<vc[u].size(); ++i) {
v = vc[u][i];
if (v==fa || v==cur)
continue;
if (!pre[v]) {
++child;
lowv = Tarjan(v, u);
lowu = min(lowu, lowv);
if (lowv >= pre[u])
++cnt[u];
} else if (pre[v] < pre[u])
lowu = min(lowu, pre[v]);
}
if (fa < )
cnt[u] = child - ;
return lowu;
} void init() {
dfs_clock = ;
memset(cnt, , sizeof(int)*n);
memset(pre, , sizeof(int)*n);
} int main() {
int i, j, k;
int ans; #ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif while (scanf("%d %d", &n, &m)!=EOF) {
for (i=; i<n; ++i)
vc[i].clear();
while (m--) {
scanf("%d %d", &i, &j);
vc[i].push_back(j);
vc[j].push_back(i);
}
ans = ;
for (cur=; cur<n; ++cur) {
init();
k = ;
for (i=; i<n; ++i) {
if (i!=cur && !pre[i]) {
++k;
Tarjan(i, -);
}
}
for (i=; i<n; ++i)
if (i!=cur)
ans = max(ans, k+cnt[i]);
}
printf("%d\n", ans);
} return ;
}