rt,用一种大众dfs + tarjan写法写挂了。输出部分如果改成 tot+1/2 就成36了。
#include<bits/stdc++.h>
#define maxn 50050
#define maxm 50050
using namespace std;
int n,m,cnt=1;
int tim;
int tot;
int dfn[maxn],low[maxn],head[maxn],belong[maxn];
struct edge{
int nxt,to;
}a[maxm];
bool ge[maxm];
vector<int> G[maxn];
long long ans=0;
void add(int x,int y){
cnt++;
a[cnt].to=y;
a[cnt].nxt=head[x];
head[x]=cnt;
}
void tarjan(int x,int fa){
dfn[x]=low[x]=++tim;
for(int i=head[x];i;i=a[i].nxt){
int u=a[i].to;
if(!dfn[u]){
tarjan(u,i);
low[x]=min(low[x],low[u]);
if(dfn[x]<low[u]){
ge[i]=ge[i^1]=true;
}
}
else if(i!=(fa^1)){
low[x]=min(low[x],dfn[u]);
}
}
}
void dfs(int x){
belong[x]=tot;
if(x){
G[tot].push_back(x);
}
for(int i=head[x];i;i=a[i].nxt){
int u=a[i].to;
if(belong[u]||ge[i]){
continue;
}
dfs(u);
}
}
int x[maxn],y[maxn];
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>x[i]>>y[i];
add(x[i],y[i]);
add(y[i],x[i]);
}
for(int i=1;i<=n;i++){
if(!dfn[i]){
tarjan(i,0);
}
}
for(int i=1;i<=n;i++){
if(!belong[i]){
tot++;
dfs(i);
}
}
cout<<(tot)/2<<endl;
return 0;
}