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

题意是给你一个无向图n个点,m条边,将m条边连接起来之后形成一个图,有Q个询问,问将u和v连接起来后图中还有多少个桥。

首先用tarjan标记点的low和dfn值,那么u和v相连的边是桥的条件是dfn[u] < low[v](说明v与u不在一个连通分量里面,v无法通过回溯到达u点,画个图模拟会清楚)。那么bridge[v]++表示u与v相连的边是桥(若是标记bridge[u]++,则最后的答案可能会出错,亲测)。要是u和v相连,不属于同一个连通分量的话会形成一个环路,那么环路里所有的桥都没有了,所以用LCA将u和v一边找公共祖节点,一边消除桥。

代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring> using namespace std;
const int MAXN = 2e5 + ;
struct data {
int next , to;
}edge[MAXN * ];
int head[MAXN] , block[MAXN] , low[MAXN] , dfn[MAXN] , st[MAXN] , dep[MAXN] , par[MAXN] , bridge[MAXN];
int top , ord , sccnum , cont , ans;
bool instack[MAXN]; void init() {
memset(head , - , sizeof(head));
memset(low , , sizeof(low));
memset(dfn , , sizeof(dfn));
memset(instack , false , sizeof(instack));
memset(bridge , , sizeof(bridge));
top = ord = sccnum = cont = ans = ;
} inline void add(int u , int v) {
edge[cont].next = head[u];
edge[cont].to = v;
head[u] = cont++;
} void tarjan(int u , int p , int d) {
low[u] = dfn[u] = ++ord;
st[++top] = u;
instack[u] = true;
par[u] = p;
dep[u] = d;
for(int i = head[u] ; ~i ; i = edge[i].next) {
int v = edge[i].to;
if(v == p)
continue;
if(!dfn[v]) {
tarjan(v , u , d + );
low[u] = min(low[v] , low[u]);
if(dfn[u] < low[v]) {
bridge[v]++;
ans++;
}
}
else if(instack[v]) {
low[u] = min(low[u] , dfn[v]);
}
}
if(low[u] == dfn[u]) {
int v;
sccnum++;
do {
v = st[top--];
instack[v] = false;
block[v] = sccnum;
}while(u != v);
}
} void lca(int u , int v) {
while(dep[u] < dep[v]) {
if(bridge[v]) {
ans--;
bridge[v]--;
}
v = par[v];
}
while(dep[u] > dep[v]) {
if(bridge[u]) {
ans--;
bridge[u]--;
}
u = par[u];
}
while(v != u) {
if(bridge[u]) {
bridge[u]--;
ans--;
}
if(bridge[v]) {
bridge[v]--;
ans--;
}
u = par[u];
v = par[v];
}
} int main()
{
int n , m , u , v , q , Case = ;
while(~scanf("%d %d" , &n , &m) && (n || m)) {
init();
while(m--) {
scanf("%d %d" , &u , &v);
add(u , v);
add(v , u);
}
tarjan( , - , );
scanf("%d" , &q);
printf("Case %d:\n" , Case++);
while(q--) {
scanf("%d %d" , &u , &v);
if(block[u] == block[v]) {
printf("%d\n" , ans);
continue;
}
lca(u , v);
printf("%d\n" , ans);
}
putchar('\n');
}
}

POJ 3694 Network (tarjan + LCA)的更多相关文章

  1. poj 3417 Network(tarjan lca)

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

  2. POJ 3694 Network(Tarjan求割边+LCA)

    Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 10969   Accepted: 4096 Descript ...

  3. poj 3694 Network(割边+lca)

    题目链接:http://poj.org/problem?id=3694 题意:一个无向图中本来有若干条桥,有Q个操作,每次加一条边(u,v),每次操作后输出桥的数目. 分析:通常的做法是:先求出该无向 ...

  4. Poj 3694 Network (连通图缩点+LCA+并查集)

    题目链接: Poj 3694 Network 题目描述: 给出一个无向连通图,加入一系列边指定的后,问还剩下多少个桥? 解题思路: 先求出图的双连通分支,然后缩点重新建图,加入一个指定的边后,求出这条 ...

  5. POJ 3694——Network——————【连通图,LCA求桥】

    Network Time Limit:5000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Stat ...

  6. poj 3694 Network : o(n) tarjan + O(n) lca + O(m) 维护 总复杂度 O(m*q)

    /** problem: http://poj.org/problem?id=3694 问每加一条边后剩下多少桥 因为是无向图,所以使用tarjan缩点后会成一棵树并维护pre数组 在树上连一条边(a ...

  7. poj 3694 pku 3694 Network tarjan求割边 lca

    题意:给你一个连通图,然后再给你n个询问,每个询问给一个点u,v表示加上u,v之后又多少个桥.一个最容易想到的办法就是先加边找桥,加边找桥,这样可定超时.那么就可以缩点,因为如果一条边不是桥那么无论怎 ...

  8. poj 3694 Network 【Tarjan】+【LCA】

    <题目链接> 题目大意: 给一个无向图,该图只有一个连通分量.然后查询q次,q < 1000, 求每次查询就增加一条边,求剩余桥的个数. 解题分析: 普通的做法就是在每加一条边后,都 ...

  9. poj 3694 Network 边双连通+LCA

    题目链接:http://poj.org/problem?id=3694 题意:n个点,m条边,给你一个连通图,然后有Q次操作,每次加入一条边(A,B),加入边后,问当前还有多少桥,输出桥的个数. 解题 ...

随机推荐

  1. Effective C++学习笔记 条款05:了解C++默默编写并调用的哪些函数

    一.如果用户没有提供构造函数.copy构造函数.copy assignment操作符和析构函数,当且仅当这些函数被需要的时候,编译器才会帮你创建出来.编译器生成的这些函数都是public且inline ...

  2. UVA 10801 Lift Hopping 电梯换乘(最短路,变形)

    题意: 有n<6部电梯,给出每部电梯可以停的一些特定的楼层,要求从0层到达第k层出来,每次换乘需要60秒,每部电梯经过每层所耗时不同,具体按 层数*电梯速度 来算.问经过多少秒到达k层(k可以为 ...

  3. 用Rational Rose来建立数据库表

    这里以MS SQL Server2000中已有的一个Northwind库为例,我们命名新的数据库名为NorthwindRose:我们只挑其中的两个表Customers和Employees做示例,另外我 ...

  4. 【 D3.js 视频系列 】 飞速入门

    本教程共包含 6 个视频,目的是为了帮助初学者快速入门,以便阅读本站其他文章. 本教程的名称为"飞速入门",是为初学者准备的,其中包括了 D3 开发中最基础的知识.对 D3 掌握得 ...

  5. Java [leetcode 3] Longest Substring Without Repeating Characters

    问题描述: Given a string, find the length of the longest substring without repeating characters. For exa ...

  6. Spring学习之Ioc

    Ioc原理讲解:http://www.cnblogs.com/xdp-gacl/p/4249939.html Ioc IoC是一种编程思想,由主动编程变为被动接收. 也就是说,所有的组件都是被动的(p ...

  7. VS2010使用EventHandler发邮件

    转:http://blog.csdn.net/alfred_72/article/details/9980279 因为不知道VS2010 Sharepoint 有EventReciver这个添加项,走 ...

  8. hdu 3948(后缀数组+RMQ)

    题意:求一个串中有多少不同的回文串. 分析:这一题的关键是如何去重,我表示我现在还没理解为什么这样去重,先放这里过两天再看!! //不同回文子串数目 #include <iostream> ...

  9. 完美完全卸载Oracle 11g数据库

    Oracle 11g可在开始菜单中卸载,然后同时需要删除注册表中相关内容. 操作系统:windows10专业版. 卸载步骤: 1.停用oracle服务:进入计算机管理,在服务中,找到oracle开头的 ...

  10. hadoop中日志聚集问题

    遇到的问题: 当点击上面的logs时,会出现下面问题: 这个解决方案为: By default, Hadoop stores the logs of each container in the nod ...