【POJ 3694】 Network(割边+LCA)

Network
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≤
AB ≤ 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 ≤ ABN), 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;
}

id=3694">

【POJ 3694】 Network(割边&lt;桥&gt;+LCA)的更多相关文章

  1. poj 3694 Network(割边+lca)

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

  2. POJ 3694 Network (求桥,边双连通分支缩点,lca)

    Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5619   Accepted: 1939 Descripti ...

  3. POJ 3694 Network(无向图求桥+重边处理+LCA)

    题目大意: 给你一个无向图,然后再给你一个Q代表有Q次询问,每一次加一条边之后还有几座桥.在这里要对重边进行处理. 每次加入一条边之后,在这条搜索树上两个点的公共祖先都上所有点的桥都没了. 这里重边的 ...

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

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

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

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

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

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

  7. [双连通分量] POJ 3694 Network

    Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 9434   Accepted: 3511 Descripti ...

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

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

  9. POJ 3694 Network(并查集缩点 + 朴素的LCA + 无向图求桥)题解

    题意:给你一个无向图,有q次操作,每次连接两个点,问你每次操作后有几个桥 思路:我们先用tarjan求出所有的桥,同时我们可以用并查集缩点,fa表示缩点后的编号,还要记录每个节点父节点pre.我们知道 ...

随机推荐

  1. 并发研究之Java内存模型(Java Memory Model)

    Java内存模型JMM java内存模型定义 上一遍文章我们讲到了CPU缓存一致性以及内存屏障问题.那么Java作为一个跨平台的语言,它的实现要面对不同的底层硬件系统,设计一个中间层模型来屏蔽底层的硬 ...

  2. VIM 报错

    syntax error: unexpected end of file if 没配对 在最后加 fi 试试 环境变量用不了 export PATH=/usr/bin:/usr/sbin:/bin:/ ...

  3. jquery----数据增删改

    简单版本 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...

  4. poj3321 dfs序+树状数组单点更新 好题!

    当初听郭炜老师讲时不是很懂,几个月内每次复习树状数组必看的题 树的dfs序映射在树状数组上进行单点修改,区间查询. /* 树状数组: lowbit[i] = i&-i C[i] = a[i-l ...

  5. Python 定值类

    1.__str__和__repr__ 如果要把一个类的实例变成 str,就需要实现特殊方法__str__(): class Person(object): def __init__(self, nam ...

  6. Spring的控制反转和依赖注入

    Spring的官网:https://spring.io/ Struts与Hibernate可以做什么事? Struts, Mvc中控制层解决方案 可以进行请求数据自动封装.类型转换.文件上传.效验… ...

  7. ThreadPoolExecutor线程池的分析和使用

    1. 引言 合理利用线程池能够带来三个好处. 第一:降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗. 第二:提高响应速度.当任务到达时,任务可以不需要等到线程创建就能立即执行. 第 ...

  8. Codeforces Round #319 (Div. 2) D - Invariance of Tree

    Invariance of Tree 题目大意:给你一个有1-n组成的序列p,让你构造一棵树,如果节点a和b之间有一条边,则p[a]和p[b]之间也有一条边. 思路:没啥思路,看了题解菜爆. 我们可以 ...

  9. 深入理解 MySQL ——锁、事务与并发控制

    本文首发于vivo互联网技术微信公众号 mp.weixin.qq.com/s/JFSDqI5ya… 作者:张硕 本文对 MySQL 数据库中有关锁.事务及并发控制的知识及其原理做了系统化的介绍和总结, ...

  10. Web大前端面试题-Day12

    1.前端需要注意哪些SEO? 合理的title.description.keywords: 搜索对着三项的权重逐个减小, title值强调重点即可, 重要关键词出现不要超过2次, 而且要靠前, 不同页 ...