缩完点后得到一棵树 求出树的直径(最长的一条链) 然后拿割边数减去直径大小就是答案
#include <bits/stdc++.h> using namespace std; struct node { int v; int next; int flag; }; node edge1[2000010],edge2[2000010]; int first1[200010],first2[200010],dfn[200010],low[200010],belong[200010]; int n,m,num,cnt,p1,p2,p,maxx; void addedge(node* edge,int* first,int u,int v) { edge[num].v=v; edge[num].next=first[u]; edge[num].flag=0; first[u]=num++; return; } void dfsI(int cur,int fa) { int tmp,i,v; num++,tmp=0; dfn[cur]=num,low[cur]=num; for(i=first1[cur];i!=-1;i=edge1[i].next) { v=edge1[i].v; if(!dfn[v]) { dfsI(v,cur); low[cur]=min(low[cur],low[v]); if(low[v]>dfn[cur]) { edge1[i].flag=1; edge1[i^1].flag=1; } } else if(v==fa) { if(tmp>0) low[cur]=min(low[cur],dfn[v]); tmp++; } else { low[cur]=min(low[cur],dfn[v]); } } return; } void dfsII(int cur) { int i,v; for(i=first1[cur];i!=-1;i=edge1[i].next) { v=edge1[i].v; if(!belong[v]&&!edge1[i].flag) { belong[v]=cnt; dfsII(v); } } return; } void tarjan() { int i,u,v; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); num=0; for(u=1;u<=n;u++) { if(!dfn[u]) { dfsI(u,-1); } } memset(belong,0,sizeof(belong)); cnt=0; for(u=1;u<=n;u++) { if(!belong[u]) { cnt++; belong[u]=cnt; dfsII(u); } } /* printf("***%d***\n",cnt); for(u=1;u<=n;u++) { printf("%d ",belong[u]); } printf("\n"); */ memset(first2,-1,sizeof(first2)); num=0; for(u=1;u<=n;u++) { for(i=first1[u];i!=-1;i=edge1[i].next) { v=edge1[i].v; if(belong[u]!=belong[v]) { addedge(edge2,first2,belong[u],belong[v]); } } } return; } void dfsIII(int cur,int fa,int dis) { int i,v,res; if(maxx<dis) { maxx=dis; p=cur; } for(i=first2[cur];i!=-1;i=edge2[i].next) { v=edge2[i].v; if(v!=fa) { dfsIII(v,cur,dis+1); } } return; } void dfsIV(int cur,int fa,int tar,int dis) { int i,v; if(cur==tar) { maxx=dis; return; } for(i=first2[cur];i!=-1;i=edge2[i].next) { v=edge2[i].v; if(v!=fa) { dfsIV(v,cur,tar,dis+1); if(maxx!=-1) return; } } return; } int main() { int i,u,v; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0&&m==0) break; memset(first1,-1,sizeof(first1)); num=0; for(i=1;i<=m;i++) { scanf("%d%d",&u,&v); addedge(edge1,first1,u,v); addedge(edge1,first1,v,u); } tarjan(); maxx=0,p1=1; dfsIII(1,-1,0); p1=p; maxx=0,p2=p1; dfsIII(p1,-1,0); p2=p; maxx=-1; dfsIV(p1,-1,p2,0); printf("%d\n",cnt-1-maxx); } return 0; }