强连通分量

来源:互联网 发布:模拟炒股软件 mac 编辑:程序博客网 时间:2024/06/08 11:19

先说一下强连通分量是个什么鬼吧。

说白了,就是在有向图的子图中任意两个点A B,A可以到B且 B可以到A就是强连通分量了。

原谅我的语文差到措辞措到没逻辑


我就说一下我常用的两种算法吧...代码丑什么的请见谅。


Tarjan:(具体内容请见上一篇blog中间部分【又懒得给链接】)

...说白了就是缩点..???

QAQ解释不清楚直接给代码算了_(:з」∠)_

void dfs(int u){dfn[u]=low[u]=++cnt;inq[u]=1;ss.push(u);for(int i=0;i<a[u].size();i++)if(!dfn[a[u][i]]){dfs(a[u][i]);low[u]=min(low[u],low[a[u][i]]);}else if(inq[a[u][i]]) low[u]=min(low[u],dfn[a[u][i]]);if(dfn[u]==low[u]){int r=0;ct++;while(r!=u&&!ss.empty()){r=ss.top();inq[r]=0;v[r]=ct;ss.pop();}}}


还有一种算法然而我自己都不知道那叫什么..QWQ

反正就是先dfs一遍后序存标号然后把边反向从标号最大的开始dfs..怎么我解释起来就那么迷之抽象呢

不管了不管了直接给代码算了

void dfs1(int u){v[u]=1;for(int i=0;i<a[u].size();i++)if(!v[a[u][i]]) dfs1(a[u][i]);c[++cnt]=u;}void dfs2(int u){v[u]=q[u]=1;ss[++s]=u;for(int i=0;i<b[u].size();i++)if(!v[b[u][i]]) dfs2(b[u][i]);}
for(i=0;i<n*4;i++)if(!v[i]) dfs1(i);for(i=0;i<n*4;i++)for(j=0;j<a[i].size();j++)b[a[i][j]].push_back(i);memset(v,0,sizeof(v));for(i=n*4;i>0;i--)if(!v[c[i]]){s=0;memset(q,0,sizeof(q));dfs2(c[i]);for(j=1;j<=s;j++)if((ss[j]<n*2&&q[ss[j]+n*2])||(ss[j]>=n*2&&q[ss[j]-n*2])) {f=1;break;}if(f) break;}

由于只是判断有没有解所以写得特别丑陋所以各位将就着看吧...



一些题目(待填坑):





原创粉丝点击