链接:http://poj.org/problem?id=3694

题意:给定一个有向连通图,每次增加一条边,求剩下的桥的数量。

思路:

给定一个无向连通图,添加一条u->v的边,求此边对图剩余的桥的数量的影响:

 若u,v在同一个边双联通分量中,则是否添加无影响。否则从u,v的LCA到u,v的边上所有的桥都不再是桥。

在Tarjan算法中,对在同一个边双联通分量中的点使用并查集合并,实现缩点,同时记录父亲节点。若u,v属于不同的边双连通分量,将dfn较大的点(设为v)向上合并直到dfn[v] < dfn[u],再将u向上合并直到u = v。合并过程中,若发现桥则剩余桥的数量减1。

合并采用并查集,要在合并过程中对路径进行优化,否则超时。

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<vector>
#include<algorithm>
const int INF = 0x3F3F3F3F;
using namespace std;
typedef long long LL; const int N=,M=;
int head[N],tot,n,m,dfn[N],deep;
int bridge;
int fa[N], cnt[N], pre[N];
struct Node{
int to,next;
}e[M];
void init(){
memset(head, -, sizeof(head));
tot = ;
bridge = ;
for(int i = ; i <= n; i++){
fa[i] = i;
cnt[i] = ;
}
} int Find(int x){
while(x != fa[x]){
x = fa[x];
}
return x;
}
bool Union(int x, int y){
int fx = Find(x);
int fy = Find(y);
if(fx!=fy){
if(cnt[fx]>cnt[fy]){
fa[fy]=fx;
cnt[fx]+=cnt[fy];
}else{
fa[fx]=fy;
cnt[fy]+=cnt[fx];
}
return true;
}else{
return false;
}
}
inline void add(int u, int to){
e[tot].to=to;
e[tot].next=head[u];
head[u]=tot++;
}
int dfs(int u, int fa){
int lowu = dfn[u] = ++deep;//lowu为u及其后代所能到达的最远祖先
for(int i=head[u];~i;i=e[i].next){
int v = e[i].to;
if(!dfn[v]){//树叶边,u到v且v未被访问
pre[v] = u;
int lowv = dfs(v, u);
lowu = min(lowu, lowv);
if(lowv > dfn[u]){
bridge++;
}else{
Union(u, v);
}
}else if(dfn[v] < dfn[u] && v != fa){
lowu = min(lowu, dfn[v]);//后向边
}
}
return lowu;
} void tarjan(){
memset(dfn, , sizeof(dfn));
deep=;
for(int i=;i<=n;i++){
if(!dfn[i]){
pre[i] = i;
dfs(i,-);
}
}
} int LCA(int u, int v){
if(Find(u) == Find(v)){
return bridge;
}
if(dfn[u] > dfn[v]){
swap(u, v);
}
while(dfn[u] < dfn[v]){
if(Union(v, pre[v])){
bridge--;
}
v = pre[v];
}
while(u != v){
if(Union(u, pre[u])){
bridge--;
}
u = pre[u];
}
return bridge;
} int main(){
int t = ;
while(~scanf("%d %d", &n, &m) && (n || m)){
init();
int a, b, q;
while(m--){
scanf("%d %d", &a, &b);
add(a, b);
add(b, a);
}
tarjan();
scanf("%d", &q);
printf("Case %d:\n",++t);
while(q--){
scanf("%d %d", &a, &b);
printf("%d\n", LCA(a, b));
}
printf("\n");
}
return ;
}

POJ3694 Network(Tarjan双联通分图 LCA 桥)的更多相关文章

  1. POJ3694 Network - Tarjan + 并查集

    Description 给定$N$个点和 $M$条边的无向联通图, 有$Q$ 次操作, 连接两个点的边, 问每次操作后的图中有几个桥 Solution 首先Tarjan找出边双联通分量, 每个双联通分 ...

  2. POJ3694 Network 边双缩点+LCA+并查集

    辣鸡错误:把dfs和ldfs搞混...QAQ 题意:给定一个无向图,然后查询q次,求每次查询就在图上增加一条边,求剩余割边的个数. 先把边双缩点,然后预处理出LCA的倍增数组: 然后加边时,从u往上跳 ...

  3. [POJ3694]Network(Tarjan,LCA)

    [POJ3694]Network Description A network administrator manages a large network. The network consists o ...

  4. Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)

    Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...

  5. poj 3417 Network(tarjan lca)

    poj 3417 Network(tarjan lca) 先给出一棵无根树,然后下面再给出m条边,把这m条边连上,然后每次你能毁掉两条边,规定一条是树边,一条是新边,问有多少种方案能使树断裂. 我们设 ...

  6. [Codeforces 555E]Case of Computer Network(Tarjan求边-双连通分量+树上差分)

    [Codeforces 555E]Case of Computer Network(Tarjan求边-双连通分量+树上差分) 题面 给出一个无向图,以及q条有向路径.问是否存在一种给边定向的方案,使得 ...

  7. 网站加载有商务通、商桥,定义js函数触发快商通代码

    有的网站已经加载了商务通.商桥的,前期定义了js函数 触发商务通.商桥代码的,可以重新定义新的函数对之前的函数进行覆盖,其 js代码为: var domain = document.domain; / ...

  8. Tarjan无向图的割点和桥(割边)全网详解&算法笔记&通俗易懂

    更好的阅读体验&惊喜&原文链接 感谢@yxc的腿部挂件 大佬,指出本文不够严谨的地方,万分感谢! Tarjan无向图的割点和桥(割边) 导言 在掌握这个算法前,咱们有几个先决条件. [ ...

  9. tarjan算法求无向图的桥、边双连通分量并缩点

    // tarjan算法求无向图的桥.边双连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> ...

随机推荐

  1. jQuery工作原理

    jQuery的开篇声明里有一段非常重要的话:jQuery是为了改变javascript的编码方式而设计的.从这段话可以看出jQuery本身并不是UI组件库或其他的一般AJAX类库.jQuery改变ja ...

  2. JQ引用

    <script type="text/javascript" src="http://files.cnblogs.com/914556495wxkj/jquery- ...

  3. mybaits in

    mybatis中的in: <select id="getByInventoryIds" resultMap="beanMap"> SELECT * ...

  4. <转>VPN技术原理

    原文地址:VPN技术原理 VPN,Virtual Private Network(虚拟专用 网络),被定义为通过一个公用网络(通常是因特网)建立一个临时的.安全的连接,是一条穿过公用网络的安全.稳定的 ...

  5. ACM/ICPC 之 DP-整数划分问题初探 (POJ1221)

    写下这道题的原因很简单= =,因为这一题的状态转移方程不好找,另一方面,我看到很多针对这一题写的解题报告都把累加状态说得模棱两可,甚至直接说成了一个单一状态,弄得本是菜鸟的我硬生生折磨了一上午画了几个 ...

  6. Django~Views

    In Django, web pages and other content are delivered by views. To get from a URL to a view, Django u ...

  7. ubuntu mysql 安装和外网访问配置

    1.输入 sudo apt-get install mysql-server 安装过程中会让你输入密码,这个密码是root的密码. 安装完毕后,就可以正常使用了,如果你需要外网用户能够连接继续下面的步 ...

  8. 跨浏览器的事件对象-------EventUtil 中的方法及用法

    什么是EventUti----封装好的事件对象 在JavaScript中,DOM0级.DOM2级与旧版本IE(8-)为对象添加事件的方法不同 为了以跨浏览器的方式处理事件,需要编写一段“通用代码”,即 ...

  9. Android环境搭建中遇到的小问题

    有一认识的同学做Android,结果他们搭建环境出现问题,最后卡在了一关,因为听说自己学过Java,所以就... 最后,自己试了一下,结果将遇到的解决问题记下来了:(看到小绿人后自己也被Android ...

  10. IOS-KVO&KVC

    KVC(key value coding) 我们一般是通过调用set方法或属性的点语法来直接更改对象的状态,即对象的属性值,比如[stu setAge:10];  stu.age = 9; lKVC, ...