【POJ 3694】 Network(割边<桥>+LCA)
Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 7971 | Accepted: 2902 |
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
题目大意:n个点的无向图 初始化有m条边
之后q次操作 每次表示在点a与点b间搭建一条边 输出对于q次操作 每次剩下的桥的条数
初始化能够用tarjan算法求出桥 对于不是割边的两个点 就能够算是在一个集合中 这样用并查集就能够进行缩点
最后生成的就是一棵树 树边就是图中的全部桥 q次询问中 每次加边<u,v> 假设u和v在一个集合中 说明新的边不会造成影响
假设u和v在两个集合中 两个集合间的边在加入<u,v>后就会失去桥的性质 这样通过LCA就能够遍历全部两个集合间的集合 在加上<u,v>这条边后 这两个集合间的集合事实上就变成了一个环 也就是能够缩成一个点 在合并集合的过程中 就能够把消失的桥从总和中减去了
代码例如以下:
#include <iostream>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>
#include <list>
#include <algorithm>
#include <map>
#include <set>
#define LL long long
#define Pr pair<int,int>
#define fread() freopen("in.in","r",stdin)
#define fwrite() freopen("out.out","w",stdout) using namespace std;
const int INF = 0x3f3f3f3f;
const int msz = 10000;
const int mod = 1e9+7;
const double eps = 1e-8; struct Edge
{
int v,next;
}; Edge eg[666666];
int head[233333];
int dfn[233333],low[233333];
int pre[233333];
int fa[233333];
bool vis[233333];
int tp,tim;
int ans; void init(int n)
{
for(int i = 1; i <= n; ++i)
pre[i] = i;
} int Find(int x)
{
return pre[x] == x? pre[x]: (pre[x] = Find(pre[x]));
} int Union(int u,int v)
{
int k = Find(u);
int r = Find(v);
if(k == r) return false;
pre[k] = r;
return true;
} void Tarjan(int u,int p)
{
vis[u] = 1;
dfn[u] = low[u] = tim++;
int v; for(int i = head[u]; i != -1; i = eg[i].next)
{
v = eg[i].v;
if(v == p) continue; if(!vis[v])
{
fa[v] = u;
Tarjan(v,u);
low[u] = min(low[u],low[v]);
if(low[v] > dfn[u])
{
ans++;
}else Union(v,u);
}
else low[u] = min(low[u],dfn[v]);
} } void lca(int u,int v)
{
if(dfn[v] < dfn[u]) swap(u,v); while(dfn[v] > dfn[u])
{
if(Union(v,fa[v]))
ans--;
v = fa[v];
} while(v != u)
{
if(Union(u,fa[u]))
ans--;
u = fa[u];
} } int main()
{
//fread();
//fwrite(); int n,m,u,v,z = 0; while(~scanf("%d%d",&n,&m) && (m+n))
{
memset(head,-1,sizeof(head));
tim = tp = 0;
init(n); while(m--)
{
scanf("%d%d",&u,&v);
eg[tp].v = v;
eg[tp].next = head[u];
head[u] = tp++; eg[tp].v = u;
eg[tp].next = head[v];
head[v] = tp++;
} memset(vis,0,sizeof(vis));
ans = 0;
fa[1] = 1;
Tarjan(1,1); int q;
scanf("%d",&q); printf("Case %d:\n",++z); while(q--)
{
scanf("%d%d",&u,&v);
lca(u,v);
printf("%d\n",ans);
}
puts("");
} return 0;
}
【POJ 3694】 Network(割边<桥>+LCA)的更多相关文章
- poj 3694 Network(割边+lca)
题目链接:http://poj.org/problem?id=3694 题意:一个无向图中本来有若干条桥,有Q个操作,每次加一条边(u,v),每次操作后输出桥的数目. 分析:通常的做法是:先求出该无向 ...
- POJ 3694 Network (求桥,边双连通分支缩点,lca)
Network Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5619 Accepted: 1939 Descripti ...
- POJ 3694 Network(无向图求桥+重边处理+LCA)
题目大意: 给你一个无向图,然后再给你一个Q代表有Q次询问,每一次加一条边之后还有几座桥.在这里要对重边进行处理. 每次加入一条边之后,在这条搜索树上两个点的公共祖先都上所有点的桥都没了. 这里重边的 ...
- poj 3694 Network 【Tarjan】+【LCA】
<题目链接> 题目大意: 给一个无向图,该图只有一个连通分量.然后查询q次,q < 1000, 求每次查询就增加一条边,求剩余桥的个数. 解题分析: 普通的做法就是在每加一条边后,都 ...
- 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
Network Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 9434 Accepted: 3511 Descripti ...
- POJ 3694 Network(Tarjan求割边+LCA)
Network Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 10969 Accepted: 4096 Descript ...
- POJ 3694 Network(并查集缩点 + 朴素的LCA + 无向图求桥)题解
题意:给你一个无向图,有q次操作,每次连接两个点,问你每次操作后有几个桥 思路:我们先用tarjan求出所有的桥,同时我们可以用并查集缩点,fa表示缩点后的编号,还要记录每个节点父节点pre.我们知道 ...
随机推荐
- hdu3486 ST表区间最值+二分
还是挺简单的,但是区间处理的时候要注意一下 #include<iostream> #include<cstring> #include<cstdio> #inclu ...
- 性能测试二十五:redis-cli 命令总结
常用命令dbsize:查看redis中的kv数量 keys *:查看redis中所有的keyset key_1 v_1:新增一个key_1,包含v_1get key_1:查看key_1中的内容del ...
- 获取更新元素文本text()
text() 方法,获取元素文本,也可以设置元素的文本值.相 <!DOCTYPE html> <html lang="en"> <head> & ...
- Asp.Net Core WebAPI入门整理(三)跨域处理
一.Core WebAPI中的跨域处理 1.在使用WebAPI项目的时候基本上都会用到跨域处理 2.Core WebAPI的项目中自带了跨域Cors的处理,不需要单独添加程序包 3.使用方法简单 ...
- [转] Nginx 配置 SSL 证书 + 搭建 HTTPS 网站教程
一.HTTPS 是什么? 根据维基百科的解释: 超文本传输安全协议(缩写:HTTPS,英语:Hypertext Transfer Protocol Secure)是超文本传输协议和SSL/TLS的组合 ...
- 朴素贝叶斯分类算法介绍及python代码实现案例
朴素贝叶斯分类算法 1.朴素贝叶斯分类算法原理 1.1.概述 贝叶斯分类算法是一大类分类算法的总称 贝叶斯分类算法以样本可能属于某类的概率来作为分类依据 朴素贝叶斯分类算法是贝叶斯分类算法中最简单的一 ...
- 【Java】 剑指offer(42) 连续子数组的最大和
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 输入一个整型数组,数组里有正数也有负数.数组中一个或连续的多个整/ ...
- 【Java】 剑指offer(67) 把字符串转换成整数
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 请你写一个函数StrToInt,实现把字符串转换成整数这个功能 ...
- HDU4372-Count the Buildings【第一类Stirling数】+【组合数】
<题目链接> <转载于 >>> > 题目大意: N座高楼,高度均不同且为1~N中的数,从前向后看能看到F个,从后向前看能看到B个,问有多少种可能的排列数. 0 ...
- 使用MSF发现主机和端口扫描
使用MSF发现主机和端口扫描 使用search命令查找需要的模块 MSF模块太多,记不住怎么办!!! 我们不需要记住所有模块,我们只要能找到我们想用的模块就行,平时积累使用的模块也行哦! 比如,我们通 ...