边双连通分量
来源:互联网 发布:影像拼接 软件 编辑:程序博客网 时间:2024/04/30 05:13
关于桥与双连通分支的定义及求法void大神给出了很详尽的介绍图的割点、桥与双连通分支
总结几条做题过程中发现的关于边双连通分量的性质:
1.将图中每个边连通分量缩为一个点后,只连端点不位于同一连通分量中的边,则将图转换成了一棵树,且树中的边都是父子边。
2.在对图进行搜索时,图中的边分为父子边和返祖边(交叉边),则一个具有n个点的边连通分量中有且仅有n-1条父子边,且可由着n-1以条边连成一棵树,剩余的边都是返祖边。
关于双连通图的构造和判定等基本问题void文章里有详细介绍,我的《连通性问题》中也有写。
poj3694 Network
题意:讯问在现有网络中添加一条边<a,b>后图中有多少条桥。
显然,若ab位于同一连通分支时不会影响桥,因此变为缩点后的树中两点之间路径上有多少条桥,由于在求双连通时记录了每个点的深度,因此不必单独求lca只需延父节点向上走,知道两个点的某个祖先相同,在寻找lca的过程中可以顺便提及出有多少条桥。
int LCA(int a, int b) {if(dfn[a]<dfn[b]){int temp=a;a=b;b=temp;}while(dfn[a]>dfn[b]){ if(bridge[a]){ sum--; bridge[a]=false; } a=fa[a]; } while(a!=b){ if(bridge[a]){sum--;bridge[a]=false;} if(bridge[b]){sum--;bridge[b]=false;} a=fa[a];b=fa[b]; }return sum;}poj1515 Street Direction / poj1438 One-Way Traffic
题意:有m条无向边确保n个点两两可达,要求将尽可能多的双向边变为单向边,使得任意两点之间仍然可达,并给出一组方案。
解法:对于无向图的桥,肯定要保持双向,对于双连通分量分量内的点,只要确保构成果敢个环就可以,一开始想到了dfs求环路,后来想到了染色,其实构成环路的边就是搜索时的父子边和返祖边,按照原本的方向构造就可以。
1438是1515的延伸,有些路已经是单向的了。其实很简单,只要在加边的时候加单向边,就相当于给一条无向边规定了性质,然后做相同的处理即可
public class Main{int maxn=1010,maxm=10010;class BCC {class node {int ne, be;int type;node(int be, int ne) {this.ne = ne;this.be = be;}}node buf[] = new node[maxm];int E[] = new int[maxn], len, n;int dfn[] = new int[maxn], low[] = new int[maxn], cnt;int vis[] = new int[maxn], fa[] = new int[maxn], sum;boolean bridge[] = new boolean[maxm];void init(int n) {this.n = n;Arrays.fill(E, -1);len = 0;}void add(int a, int b) {buf[len] = new node(b, E[a]);E[a] = len++;buf[len] = new node(a, E[b]);E[b] = len++;}void dfs(int a) {vis[a] = 1;dfn[a] = low[a] = ++cnt;for (int i = E[a]; i != -1; i = buf[i].ne) {int b = buf[i].be;if (vis[b] == 1 && b != fa[a]){buf[i].type=1;//返祖边low[a] = Math.min(low[a], dfn[b]);}if (vis[b] == 0) {buf[i].type=2;//父子边fa[b] = a;dfs(b);low[a] = Math.min(low[b], low[a]);if (low[b] > dfn[a]) {buf[i].type=3;////System.out.println(a+" bb "+b+" "+i);}}}vis[a] = 2;}void solve() {Arrays.fill(dfn, 0);Arrays.fill(low, 0);Arrays.fill(bridge, false);Arrays.fill(vis, 0);cnt = sum = 0;for (int i = 1; i <= n; i++)fa[i] = i;dfs(1);}void go(){for(int i=1;i<=n;i++)for(int j=E[i];j!=-1;j=buf[j].ne){//System.out.println(i+" "+j);if(buf[j].type==0)continue;int b=buf[j].be; System.out.println(i+" "+b);if(buf[j].type==3)System.out.println(b+" "+i);}}}StreamTokenizer in = new StreamTokenizer(new BufferedReader( new InputStreamReader(System.in))); int nextInt() throws IOException { in.nextToken(); return (int) in.nval; } BCC bcc=new BCC(); void run() throws IOException { int cas=0; while(++cas>0){ int n=nextInt(); int m=nextInt(); if(n==0) break; System.out.println(cas+"\n"); bcc.init(n); for(int i=1;i<=m;i++) bcc.add(nextInt(), nextInt()); bcc.solve(); bcc.go(); System.out.println("#"); } }public static void main(String[] args) throws IOException {new Main().run();}}
- 边双连通分量
- 点-双连通分量&边-双连通分量复习笔记
- 边双连通分量模版
- HDU4738【边双连通分量】
- 边双连通分量模板
- POJ 3352 边的双连通分量
- HDU 3390 Railway 边双连通分量
- POJ3177_Redundant_Paths_边双连通分量_tarjan
- hdu 2242(边双连通分量)
- poj 3352(边双连通分量)
- uva 10972(边双连通分量)
- poj3177 Redundant Paths 边双连通分量
- 点/边 双连通分量---Tarjan算法
- hdu 2460(边双连通分量+LCA)
- POJ3177 求边双连通分量
- tarjan算法之 边双连通分量
- 边的双连通分量问题
- poj3352 Road Construction(边双连通分量)
- HttpSessionListener用法
- HDU Boring counting 树状数组
- 局部变量、全局变量、堆、堆栈、静态和全局
- 学习MongoDB--(6-1):聚合(初级聚合函数使用)
- 学习MongoDB--(6-2):聚合(MapReduce使用)
- 边双连通分量
- 转载:面试技巧70招
- POJ1664
- OpenGL ES之glLightModel函数
- xhprof安装&&使用
- windows2003server域服务器配置说明
- hdu 4341 Gold miner 需要处理的分组背包 蛮有意义的题目
- 电脑蓝屏代码和解决方案
- HDOJ 2147 kiki’s game