图论基础算法
来源:互联网 发布:软件项目介绍书 编辑:程序博客网 时间:2024/05/16 10:16
这些东西本来去年就会的……然而由于太久没打(其实真相是整天都在浪),于是在某一天我惊奇地发现早已忘记……
首先,是有向图的强连通分量……我写的是tarjan算法(卧槽tarjan这人怎么这么6,splay,lca,强连通分量都跟他有关系)
这里有一道题目:codevs 2822(顺手把一年前没a的题a了)
强连通分量中边只有三种,一种是树边,一种是返祖边,还有一种不知道叫什么边(反正这种边都没用)
显然只有树边和返祖边有用
对于一个节点,他的颜色可能有三种,黑白灰,白表示这个节点还没有被访问过,灰表示在栈里,黑表示已出栈
我们需要两个数组:low数组用来记录他的子树的返祖边指向深度最浅的祖先的深度,dfn表示他的编号(也叫时间戳)
low(u)=
min{
dfn(u)
low(v) (u,v)为树边
dfn(v) (u,v)为返祖边
}
如果满足low(u)==dfn(u)那么说明u和当前栈里还没出栈的深度比u深的节点都属于一个强连通分量
什么?无向图的双连通分量?
一样的……只要记录上一个节点防止死循环就好了……
割点:把这个点去掉之后连通分量数量增加
桥:把这条边去掉之后连通分量数量增加
割点求法:有两种情况
1,根有超过两棵子树,此时根为割点
2,存在树边u,v,使得low(v)>=dfn(u)
桥求法:树边u,v,使得low(v)>dfn(u)
割点例题:poj1174
桥例题:hdu4738
强连通分量code:
void dfs(int now)
{
s.push(now);
low[now]=dfn[now]=++tot;
vis[now]++;
for (int ii=0;ii<g[now].size();ii++) if (!vis[g[now][ii]]){
dfs(g[now][ii]);
low[now]=min(low[now],low[g[now][ii]]);
}
else if (vis[g[now][ii]]==1){
low[now]=min(low[now],dfn[g[now][ii]]);
}
if (low[now]==dfn[now]){
if (!s.empty()){
int jb=s.top();s.pop();
ans++;
while (jb!=now){
fa[jb]=ans;
size[ans]++;
vis[jb]++;
jb=s.top();s.pop();
}
fa[jb]=ans;
size[ans]++;
vis[jb]++;
}
}
}
- 图论算法基础
- 图论基础算法
- 图论基础算法
- 基础图论算法导引
- 基础图论问题算法总结
- 图论基础算法(持续更新)
- 【数模集】 图论常用算法 基础
- 【NOIp复习】图论基础算法
- 图论算法基础-BFS与DFS
- HDU 1863 (图论基础prim算法)
- HDU 1875(图论基础prim算法)
- Java图算法之基础
- Dijkstra求单源最短路径(图论基础算法)
- 数据结构----图论基础算法的小合集(1)
- 算法竞赛入门经典第6章:图论基础
- 算法基础
- 算法基础
- 算法基础
- 【笔记】 《js权威指南》- 第7章 数组
- 字符串编辑距离
- 随便看看
- 博客专栏:二十三种设计模式之开篇
- 光纤与PON基础概念整理
- 图论基础算法
- 用Lazarus编写第一个程序Pascal版的hello world
- Linux -- uname命令查询操作系统
- OSX 修改环境变量
- MingW Cmake bulid OpenCV
- android MediaCodec 音频编解码的实现——转码
- 二叉树(1)基本概念以及三种遍历
- 关于象棋最短路径的一个问题
- JDK 1.7 Integer.parseInt 源码解析