POJ3694(KB9-D 割边+LCA)
Network
| Time Limit: 5000MS | Memory Limit: 65536K | |
| Total Submissions: 10371 | Accepted: 3853 |
Description
A network administrator manages a large network. The network consists of N computers and M links between pairs of computers. Any pair of computers are connected directly or indirectly by successive links, so data can be transformed between any two computers. The administrator finds that some links are vital to the network, because failure of any one of them can cause that data can't be transformed between some computers. He call such a link a bridge. He is planning to add some new links one by one to eliminate all bridges.
You are to help the administrator by reporting the number of bridges in the network after each new link is added.
Input
The input consists of multiple test cases. Each test case starts with a line containing two integers N(1 ≤ N ≤ 100,000) and M(N - 1 ≤ M ≤ 200,000).
Each of the following M lines contains two integers A and B ( 1≤ A ≠ B ≤ N), which indicates a link between computer A and B. Computers are numbered from 1 to N. It is guaranteed that any two computers are connected in the initial network.
The next line contains a single integer Q ( 1 ≤ Q ≤ 1,000), which is the number of new links the administrator plans to add to the network one by one.
The i-th line of the following Q lines contains two integer A and B (1 ≤ A ≠ B ≤ N), which is the i-th added new link connecting computer A and B.
The last test case is followed by a line containing two zeros.
Output
For each test case, print a line containing the test case number( beginning with 1) and Q lines, the i-th of which contains a integer indicating the number of bridges in the network after the first i new links are added. Print a blank line after the output for each test case.
Sample Input
3 2
1 2
2 3
2
1 2
1 3
4 4
1 2
2 1
2 3
1 4
2
1 2
3 4
0 0
Sample Output
Case 1:
1
0
Case 2:
2
0
Source
割边:在连通图中,删除了连通图的某条边后,图不再连通。这样的边被称为割边,也叫做桥。
割点:在连通图中,删除了连通图的某个点以及与这个点相连的边后,图不再连通。这样的点被称为割点。
DFS搜索树:用DFS对图进行遍历时,按照遍历次序的不同,我们可以得到一棵DFS搜索树。

树边:在搜索树中的蓝色线所示,可理解为在DFS过程中访问未访问节点时所经过的边,也称为父子边
回边:在搜索树中的橙色线所示,可理解为在DFS过程中遇到已访问节点时所经过的边,也称为返祖边、后向边
观察DFS搜索树,我们可以发现有两类节点可以成为割点。对根节点u,若其有两棵或两棵以上的子树,则该根结点u为割点;对非叶子节点u(非根节点),若其中的某棵子树的节点均没有指向u的祖先节点的回边,说明删除u之后,根结点与该棵子树的节点不再连通;则节点u为割点。对于根结点,显然很好处理;但是对于非叶子节点,怎么去判断有没有回边是一个值得深思的问题。我们用dfn[u]记录节点u在DFS过程中被遍历到的次序号,low[u]记录节点u或u的子树通过非父子边追溯到最早的祖先节点(即DFS次序号最小),那么low[u]的计算过程如下。

对于给的例子,其求出的dfn和low数组如下。
id 123456
dfn 123456
low 111444
可以发现,对于情况2,当(u,v)为树边且low[v]≥dfn[u]时,节点u才为割点。而当(u,v)为树边且low[v]>dfn[u]时,表示v节点只能通过该边(u,v)与u连通,那么(u,v)即为割边。tarjan算法的时间复杂度是O(n+m)的,非常快。
题意:给出一幅无向图,然后进行加边,每加一条边,询问图中割边的数量
思路:每次加边,把u-v-lca(u,v)-u这个环上的割边减掉。
//2017-08-20
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; const int N = ;
const int M = ;
int head[N], tot;
struct Edge{
int to, next;
}edge[M<<]; void init(){
tot = ;
memset(head, -, sizeof(head));
} void add_edge(int u, int v){
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++; edge[tot].to = u;
edge[tot].next = head[v];
head[v] = tot++;
} int n, m, deep, ans;
int dfn[N];//dfn[u]记录节点u在DFS过程中被遍历到的次序号
int low[N]; //low[u]记录节点u或u的子树通过非父子边追溯到最早的祖先节点(即DFS次序号最小)
int fa[N];//保存dfs树的信息
int level[N];//记录节点在dfs树中的深度
int bridge[N];//记录割边,若bridge[u] == 1, 则<u, fa[u]>为一条割边 void tarjan(int u, int father){
fa[u] = father;
dfn[u] = low[u] = deep++;
level[u] = level[father]+;
for(int i = head[u]; i != -; i = edge[i].next){
int v = edge[i].to;
if(dfn[v] == -){
tarjan(v, u);
low[u] = min(low[u], low[v]);
if(low[v] > dfn[u]){
bridge[v] = ;
ans++;
}
}else if(v != father)
low[u] = min(low[u], dfn[v]);
}
} void lca(int a, int b){
while(level[a] > level[b]){
if(bridge[a]){
ans--;
bridge[a] = ;
}
a = fa[a];
}
while(level[b] > level[a]){
if(bridge[b]){
ans--;
bridge[b] = ;
}
b = fa[b];
}
while(a != b){
if(bridge[a]){
ans--;
bridge[a] = ;
}
if(bridge[b]){
ans--;
bridge[b] = ;
}
a = fa[a];
b = fa[b];
}
} int main()
{
//freopen("inputD.txt", "r", stdin);
int kase = ;
while(scanf("%d%d", &n, &m)!=EOF && (n || m)){
printf("Case %d:\n", ++kase);
init();
int u, v;
for(int i = ; i < m; i++){
scanf("%d%d", &u, &v);
add_edge(u, v);
}
memset(bridge, , sizeof(bridge));
memset(dfn, -, sizeof(dfn));
memset(low, , sizeof(low));
level[] = ;
deep = ;
tarjan(, );
int q;
scanf("%d", &q);
while(q--){
scanf("%d%d", &u, &v);
if(ans)lca(u, v);
printf("%d\n", ans);
}
printf("\n");
} return ;
}
POJ3694(KB9-D 割边+LCA)的更多相关文章
- poj 3694(割边+lca)
题意:给你一个无向图,可能有重边,有q次询问,问你每次我添加一条边,添加后这个图还有多少个桥 解题思路:首先先把所有没有割边的点对缩成一个联通块,无向图一般并查集判环,然后就得到一个割边树,给你一条新 ...
- POJ 3694 Network(Tarjan求割边+LCA)
Network Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 10969 Accepted: 4096 Descript ...
- POJ3694 Network(连通图+LCA)
题目链接:http://poj.org/problem?id=3694 题目大意:给定一个图,每次添加一条边(可能有重边).输出每次添加后桥的 数目.由于添加边的次数比较多,添加一次Tarjin一次明 ...
- poj 3694 pku 3694 Network tarjan求割边 lca
题意:给你一个连通图,然后再给你n个询问,每个询问给一个点u,v表示加上u,v之后又多少个桥.一个最容易想到的办法就是先加边找桥,加边找桥,这样可定超时.那么就可以缩点,因为如果一条边不是桥那么无论怎 ...
- poj 3694 Network(割边+lca)
题目链接:http://poj.org/problem?id=3694 题意:一个无向图中本来有若干条桥,有Q个操作,每次加一条边(u,v),每次操作后输出桥的数目. 分析:通常的做法是:先求出该无向 ...
- POJ3694 Network【连通分量+LCA】
题意: 一个无向图可以有重边,下面q个操作,每次在两个点间连接一条有向边,每次连接后整个无向图还剩下多少桥(注意是要考虑之前连了的边,每次回答是在上一次的基础之上). 思路: 首先运行一次Tarjan ...
- Network(POJ3694+边双连通分量+LCA)
题目链接:http://poj.org/problem?id=3694 题目: 题意:给你一个n个点m条边的无向连通图,进行q次操作,每次操作在u和v之间加一条边,问每次操作之后“桥”的数量. 思路: ...
- poj3694 边-双连通分量+lca
题意:先给了一张无向图,然后依次加边,每次求桥的数量 题解:先用一次tarjan,我们可以标记桥的位置和记录桥的数量同时记录fa数组,然后更新边的时候我们可以用lca,因为在tarjan缩点之后得到了 ...
- 【POJ 3694】 Network(割边<桥>+LCA)
[POJ 3694] Network(割边+LCA) Network Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 7971 ...
随机推荐
- SQL注入之PHP-MySQL实现手工注入-数字型
SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎 ...
- Linux巩固记录(9) keepalived+nginx搭建高可用负载分发环境
环境准备(继续服用hadoop节点) slave1 192.168.2.201(CentOs 7) slave2 192.168.2.202(CentOs 7) slave1 和 slave2 上 ...
- vue项目经验:图形验证码接口get请求处理
一般图形验证码处理: 直接把img标签的src指向这个接口,然后在img上绑定点击事件,点击的时候更改src的地址(在原来的接口地址后面加上随机数即可,避免缓存) <img :src=" ...
- gensim与numpy array 互转
目的 将gensim输出的格式转化为numpy array格式,支持作为scikit-learn,tensorflow的输入 实施 使用nltk库的停用词和网上收集的资料整合成一份新的停用词表,用来过 ...
- sql必知必会
1.根据条件查询数据库中数据,并返回数据条数 去掉count就会返回数据库中符合条件的所有数据 SELECT COUNT(*) FROM sentiment_info WHERE sentiment_ ...
- xamarin 编译出现Xamarin.Build.Forms.Tasks.GetTaskAbi 无法加载的错误解决方法
最新升级最新的vs2017后发现编译xamarin forms 会出现错误 Xamarin.Forms.Build.Tasks.GetTasksAbi task could not be loaded ...
- nginx在centos 7中源码编译安装【添加grpc的支持】
安装依赖软件 1.安装编译工具gcc gcc是一个开源编译器集合,用于处理各种各样的语言:C.C++.Java.Ada等,在linux世界中是最通用的编译器,支持大量处理器:x86.AMD64.Pow ...
- opencv2函数学习之threshold:实现图像阈值化
在opencv2中,threshold函数可以进行阈值化操作. double threshold( const Mat& src, Mat& dst, double thresh,do ...
- CDH 版本子节点启动问题
今天下午整整为了启动一个节点瞎忙活一下午,惨痛的教训还是记录下来吧,毕竟付出了代价.事情原委,一个同事在一台机器上占用了大量内存训练CTR点击率模型,而这台机器上部署了分布式Hadoop的一个data ...
- (转)Python3之requests模块
原文:https://www.cnblogs.com/wang-yc/p/5623711.html Python标准库中提供了:urllib等模块以供Http请求,但是,它的 API 太渣了.它是为另 ...