我很不要脸的直接安利ATP大佬的blog了(原谅我大yz风气习惯把女生叫做大佬)
放置一些ban(突然想到某农药)子。
int z,dfn[110000],low[110000]; int top,sta[110000];bool v[110000]; int cnt,belong[110000]; void strong_unicom(int x) { dfn[x]=low[x]++z; sta[++top]=x;v[x]=true; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(dfn[y]==0) { strong_unicom(y); low[x]=min(low[x],low[y]); } else { if(v[y]==true) low[x]=min(low[x],dfn[y]); } } if(dfn[x]==low[x]) { int i;cnt++; do { i=sta[top];top--; v[i]=false; belong[i]=cnt; }while(i!=x); } } //----------------function-------------------- z=top=cnt=0; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(v,false,sizeof(v)); for(int i=1;i<=n;i++) if(dfn[i]==0)strong_unicom(i); //------------------main-------------------
曾经大家都很纠结一个问题
low[x]=min(low[x],dfn[y]);换成low[x]=min(low[x],low[y]);
也可以AC,现在明白了,是强调割点的意义。
int z,dfn[110000],low[110000],cut[110000]; void findcut(int x) { dfn[x]=low[x]=++z; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(dfn[y]==0) { findcut(y); low[x]=min(low[x],low[y]); if(low[y]>=dfn[x])cut[x]++; } else low[x]=min(low[x],dfn[y]); } } //----------------function-------------------- z=0; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(cut,0,sizeof(cut)); for(int i=1;i<=n;i++) if(dfn[i]==0)findcut(i); else cut[i]++; //------------------main-------------------