图论基础算法
2016-04-03 11:55
232 查看
这些东西本来去年就会的……然而由于太久没打(其实真相是整天都在浪),于是在某一天我惊奇地发现早已忘记……
首先,是有向图的强连通分量……我写的是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]++;
}
}
}
首先,是有向图的强连通分量……我写的是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]++;
}
}
}
相关文章推荐
- python笔记(持续更新)
- lintcode: 生成括号
- 在Linux下使用NTFS-3G挂载NTFS文件系统
- 史上最新版GitHub+Hexo配置系列教程-Hexo配置(一)
- hdoj 2026 首字母变大写 (字符串)
- 在C#环境中动态调用IronPython脚本(一)
- leetcode——112——Path Sum
- 软件安装与仿真设置 -- 慕司板IAP15
- android6.0以后删除HttpClient的解决方法
- Android-Studio-插件小结
- 正宗快排
- 对称加密之AES加密
- 支持向量机SVM(五)
- 2016年网易春招软件测试实习生面试
- [转] 记住这14条 关键时刻可以救命!学着保护好自己!
- memset函数
- web进修之—Hibernate 继承映射(5)
- 支持向量机SVM(四)
- Python Discuz 7.2 faq.php 注入漏洞全自动利用工具
- jquery uploadify在IE上传报406HttpError