题意:无向联通图,求一条最长的路径,路径长度定义为u到v必须经过的边的个数
如果把强联通分量都缩成一个点以后,每个点内部的边都是可替代的;而又因为这是个无向图,缩完点以后就是棵树,跑两遍dfs求直径即可
1 #include2 #define pa pair 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 using namespace std; 5 typedef long long ll; 6 const int maxn=3e5+10; 7 8 inline ll rd(){ 9 ll x=0;char c=getchar();int neg=1;10 while(c<'0'||c>'9'){ if(c=='-') neg=-1;c=getchar();}11 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();12 return x*neg;13 }14 15 int eg[maxn*2][2],egh[maxn],ect;16 int eg2[maxn*2][2],egh2[maxn],ect2;17 int N,M,dfn[maxn],tot,low[maxn],stk[maxn],sh,bel[maxn];18 int ma,xx;19 bool instk[maxn];20 21 inline void adeg(int a,int b){22 eg[++ect][0]=b,eg[ect][1]=egh[a],egh[a]=ect;23 }24 inline void adeg2(int a,int b){25 eg2[++ect2][0]=b,eg2[ect2][1]=egh2[a],egh2[a]=ect2;26 }27 28 void tarjan(int x,int f){29 dfn[x]=low[x]=++tot;instk[x]=1;stk[++sh]=x;30 for(int i=egh[x];i;i=eg[i][1]){31 int b=eg[i][0];if(b==f) continue;32 if(!dfn[b]) tarjan(b,x),low[x]=min(low[x],low[b]);33 else if(instk[b]) low[x]=min(low[x],dfn[b]);34 }35 if(dfn[x]==low[x]){36 while(1){37 bel[stk[sh]]=x,instk[stk[sh]]=1;38 if(stk[sh--]==x) break;39 }40 }41 }42 43 void dfs(int x,int f,int dis){44 if(dis>ma) ma=dis,xx=x;45 for(int i=egh2[x];i;i=eg2[i][1]){46 int b=eg2[i][0];47 if(b==f) continue;48 dfs(b,x,dis+1);49 }50 }51 52 int main(){53 int i,j,k;54 N=rd(),M=rd();55 for(i=1;i<=M;i++){56 int a=rd(),b=rd();57 adeg(a,b);adeg(b,a);58 }59 tarjan(1,0);60 for(i=1;i<=N;i++){61 for(j=egh[i];j;j=eg[j][1]){62 int b=eg[j][0];63 if(bel[i]==bel[b]) continue;64 adeg2(bel[i],bel[b]);65 }66 }67 ma=0;xx=bel[1];68 dfs(bel[1],0,0);69 dfs(xx,0,0);70 printf("%d\n",ma);71 return 0;72 }