题目描述:给一个无向连通图,至少添加几条边使得去掉图中任意一条边不改变图的连通性(即使得它变为边双连通图)
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=1e5+5;
struct node{
int v,nxt,id;
}e[maxn];
int n,m,head[maxn],tot,cnt,low[maxn],dfn[maxn],degree[maxn];
void init(){
tot=1,cnt=0;
memset(head,-1,sizeof(head));
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(degree,0,sizeof(degree));
}
void add(int u,int v,int id){
e[tot].v=v;
e[tot].id=id;
e[tot].nxt=head[u];
head[u]=tot++;
}
void tarjan(int u,int pre){
low[u]=dfn[u]=++cnt;
for(int i=head[u];i!=-1;i=e[i].nxt){
int v=e[i].v;
int id=e[i].id;
if(!dfn[v]){
tarjan(v,id);
low[u]=min(low[u],low[v]);
}
else if(pre!=id)low[u]=min(low[u],dfn[v]);
}
}
int main(){
ios::sync_with_stdio(false);
init();
cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
add(x,y,i);
add(y,x,i);
}
tarjan(1,-1);
for(int u=1;u<=n;u++){
for(int i=head[u];i!=-1;i=e[i].nxt){
int v=e[i].v;
if(low[u]!=low[v]) degree[low[v]]++;
}
}
int ans=0;
for(int i=1;i<=n;i++){
if(degree[i]==1)ans++;
}
cout<<(ans+1)/2<<endl;
}