POJ 3694 Network (tarjan + LCA)
题目链接: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)的更多相关文章
- poj 3417 Network(tarjan lca)
poj 3417 Network(tarjan lca) 先给出一棵无根树,然后下面再给出m条边,把这m条边连上,然后每次你能毁掉两条边,规定一条是树边,一条是新边,问有多少种方案能使树断裂. 我们设 ...
- POJ 3694 Network(Tarjan求割边+LCA)
Network Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 10969 Accepted: 4096 Descript ...
- poj 3694 Network(割边+lca)
题目链接:http://poj.org/problem?id=3694 题意:一个无向图中本来有若干条桥,有Q个操作,每次加一条边(u,v),每次操作后输出桥的数目. 分析:通常的做法是:先求出该无向 ...
- Poj 3694 Network (连通图缩点+LCA+并查集)
题目链接: Poj 3694 Network 题目描述: 给出一个无向连通图,加入一系列边指定的后,问还剩下多少个桥? 解题思路: 先求出图的双连通分支,然后缩点重新建图,加入一个指定的边后,求出这条 ...
- POJ 3694——Network——————【连通图,LCA求桥】
Network Time Limit:5000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Stat ...
- poj 3694 Network : o(n) tarjan + O(n) lca + O(m) 维护 总复杂度 O(m*q)
/** problem: http://poj.org/problem?id=3694 问每加一条边后剩下多少桥 因为是无向图,所以使用tarjan缩点后会成一棵树并维护pre数组 在树上连一条边(a ...
- poj 3694 pku 3694 Network tarjan求割边 lca
题意:给你一个连通图,然后再给你n个询问,每个询问给一个点u,v表示加上u,v之后又多少个桥.一个最容易想到的办法就是先加边找桥,加边找桥,这样可定超时.那么就可以缩点,因为如果一条边不是桥那么无论怎 ...
- poj 3694 Network 【Tarjan】+【LCA】
<题目链接> 题目大意: 给一个无向图,该图只有一个连通分量.然后查询q次,q < 1000, 求每次查询就增加一条边,求剩余桥的个数. 解题分析: 普通的做法就是在每加一条边后,都 ...
- poj 3694 Network 边双连通+LCA
题目链接:http://poj.org/problem?id=3694 题意:n个点,m条边,给你一个连通图,然后有Q次操作,每次加入一条边(A,B),加入边后,问当前还有多少桥,输出桥的个数. 解题 ...
随机推荐
- CSS在不同浏览器兼容问题,margin偏移/offset溢出等
margin在垂直取值时取最大值 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "h ...
- SetCapture、ReleaseCapture、GetCapture
正常情况下,鼠标指针位于哪个窗口区域内,鼠标消息就自动发给哪个窗口.如果调用了SetCapture,之后无论鼠标的位置在哪,鼠标消息都发给指定的这个窗口,直到调用ReleaseCapture或者调用S ...
- Qt之进程间通信(QProcess)
简述 QProcess可以在应用程序内部与其它进程通信,或启动其它应用程序.与在终端机之类的命令输入窗口上使用名称和参数是一样的,可以使用QProcess提供的函数start()启动进程.可以注册QS ...
- Android 开发问题集合
1.屏幕横.竖切换 修改“AndroidManifest.xml”的android:screenOrientation 一般需要:landscape.portrait 2.修改应用名字 修改“Andr ...
- LeetCode Binary Tree Level Order Traversal II (二叉树颠倒层序)
题意:从左到右统计将同一层的值放在同一个容器vector中,要求上下颠倒,左右不颠倒. 思路:广搜逐层添加进来,最后再反转. /** * Definition for a binary tree no ...
- django - 替换admin的textarea为 富文本
1. 安装这个:https://github.com/pydanny/django-wysiwyg 2. 下载你希望的 编辑器,到你的指定路径STATIC_ROOT [详细后面补充]
- 搭建LAMP测试环境
LAMP:Linux+Apache+Mysql+Php,组合统称为LAMP,关于其中的独立个体,这里就不多介绍了. 1.首先准备一下软件包,如下: mysql-5.0.22.tar.gz httpd- ...
- 【Struts】服务器文件的上传和下载
Java中获得文件的文件后缀 import java.io.*; public class FileTest{ public static void main(String args[]){ File ...
- 【转】Android SwitchButton(滑动开关)
原文网址:http://blog.csdn.net/wangjinyu501/article/details/27961303 版本:1.0 日期:2014.5.17 2014.6.1 版权:© 20 ...
- 【转】Linux时间函数之gettimeofday()函数之使用方法
原文网址:http://blog.csdn.net/tigerjibo/article/details/7039434 一.gettimeofday()函数的使用方法: 1.简介: 在C语言中可以使用 ...