【模板】tarjan
【强连通分量,缩点】就是寻找环
int tarjan(int x){ dfn[x]=low[x]=++tot; s.push(x); sta[x]=1; for(int i=last[x];i;i=a[i].next){//邻接表 int y=a[i].to; if(dfn[y]==0){ tarjan(y); low[x]=Min(low[x],low[y]); } else if(sta[y]==1) low[x]=Min(low[x],dfn[y]); } if(dfn[x]==low[x]){ int k=0; Color++; while(x!=k){ k=s.top(); s.pop(); sta[k]=0; color[k]=Color; num[Color]++; } } return 0; }
【割桥】
int tarjan(int x,int father){ dfn[x]=low[x]=++tot; for(int i=last[x];i;i=a[i].next){ int y=a[i].to; if(dfn[y]==0){ tarjan(y,x); if(low[y]>dfn[x]){ ans[++Ans].l=x; ans[Ans].r=y; } low[x]=Min(low[x],low[y]); continue; } else if(y!=father) low[x]=Min(low[x],dfn[y]); } }
【割点】
int tarjan(int x,int father){ int child=0; dfn[x]=low[x]=++tot; for(int i=last[x];i;i=a[i].next){ int y=a[i].to; if(dfn[y]==0){ tarjan(y,x); low[x]=Min(low[x],low[y]); if(low[y]>=dfn[x]){ child++; if(child>1||root!=x) cut[x]=1;//不能直接存,会有重复点 } } else if(y!=father) low[x]=Min(low[x],dfn[y]); } } int main(){ (略( ̄┰ ̄*)……) int Ans=0; for(int i=1;i<=n;i++) if(cut[i]==1) ans[++Ans]=i; printf("%d\n",Ans); for(int i=1;i<=Ans;i++) printf("%d ",ans[i]); }

浙公网安备 33010602011771号