求割点
注意删除一个点的时候,会使连通分量数减少
#include <cstdio>
#include <deque>
#include <set>
#include <string>
#include <map>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
typedef long long LL;
const int maxn = 5005;
const int inf = 0x3f3f3f3f;
struct node{
int v;
int next;
}e[maxn*2];
int head[maxn];
int tot;
int n,m;
int idel;
int low[maxn];
int dfn[maxn];
int cut[maxn];
bool instack[maxn];
int id;
template<class T> void checkmax(T &a,T b){
if(b > a)a = b;
}
void add(int u,int v){
e[tot].v = v;
e[tot].next = head[u];
head[u] = tot ++;
}
void init(){
memset(head,-1,sizeof(head));
tot = 0;
}
void Tarjan(int u,int pre){
dfn[u] = low[u] = id ++;
instack[u] = true;
int child = 0;
for(int i=head[u];i!=-1;i=e[i].next){
int v = e[i].v;
if(v == pre)continue;
if(v == idel)continue;
if(dfn[v] == -1 ){
child ++;
Tarjan(v,u);
low[u] = min(low[u],low[v]);
if(pre != -1 && low[v] >= dfn[u]){
cut[u] ++;
}
}
else if(instack[v] == true){
low[u] = min(low[u],dfn[v]);
}
}
if(pre == -1){
cut[u] = child - 1;
}
instack[u] = false;
}
int gao(){
memset(instack,false,sizeof(instack));
memset(dfn,-1,sizeof(dfn));
memset(cut,0,sizeof(cut));
id = 0;
int cnt = 0;
int ans = 0;
for(int i=0;i<n;i++){
if(i != idel && dfn[i] == -1){
Tarjan(i,-1);
cnt ++;
}
}
for(int i=0;i<n;i++){
//zhuyizhiyou yigedian de shihou
if(i != idel)ans = max(ans,cnt + cut[i]);
}
return ans;
}
int main(){
while(scanf("%d%d",&n,&m)!=-1){
init();
for(int i=0;i<m;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
int ans = 0;
for(idel=0;idel<n;idel++){
ans = max(ans,gao());
}
printf("%d\n",ans);
}
return 0;
}