标签:++ string tarjan bsp 等于 -- name iostream 割边
#include<cstdio> #include<cstdlib> #include<algorithm> #include<iostream> #include<cstring> using namespace std; const int maxn=10010; const int maxm=200010; int Laxt[maxn],Next[maxm],To[maxm],cnt,vis[maxn]; int dfn[maxn],low[maxn]; int times,ans,cute_cnt,n,m; int q[maxn],q_cnt,scc[maxn],scc_cnt; int stk[maxn],top; void _init() { memset(Laxt,0,sizeof(Laxt)); memset(dfn,0,sizeof(dfn)); memset(scc,0,sizeof(scc)); memset(vis,0,sizeof(vis)); ans=cute_cnt=top=scc_cnt=cnt=times=0; } void _add(int u,int v) { Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v; } void _count()//找环 { int e=0; for(int i=1;i<=q_cnt;i++) for(int j=Laxt[q[i]];j;j=Next[j]) if(scc[To[j]]==scc[q[i]]) e++; e/=2; if(e>q_cnt) ans+=e; } void _tarjan(int u,int v){ dfn[u]=low[u]=++times; int num_v=0; stk[++top]=u; for(int i=Laxt[u];i;i=Next[i]){ if(To[i]==v) continue;//此题无重边 if(!dfn[To[i]]){ _tarjan(To[i],u); if(low[u]>low[To[i]]) low[u]=low[To[i]]; if(low[To[i]]>dfn[u]) cute_cnt++;//割边 if(dfn[u]<=low[To[i]]){//小于是个环,等于是个点,都要处理 q_cnt=0;//环内的点 scc_cnt++; for(;;){ int tmp=stk[top--]; scc[tmp]=scc_cnt; q[++q_cnt]=tmp; if(tmp==To[i]) break; } scc[u]=scc_cnt; q[++q_cnt]=u; _count(); } } else if(dfn[To[i]]<low[u]) low[u]=dfn[To[i]]; } } int main() { int i,j,k,u,v; while(~scanf("%d%d",&n,&m)){ if(n==0&&m==0) return 0; _init(); while(m--){ scanf("%d%d",&u,&v); u++;v++; _add(u,v); _add(v,u); } for(i=1;i<=n;i++) if(!dfn[i]) _tarjan(i,-1); printf("%d %d\n",cute_cnt,ans); } return 0; }
标签:++ string tarjan bsp 等于 -- name iostream 割边
原文地址:http://www.cnblogs.com/hua-dong/p/7694057.html