POJ 3694 Network (求桥,边双连通分支缩点,lca)
| Time Limit: 5000MS | Memory Limit: 65536K | |
| Total Submissions: 5619 | Accepted: 1939 |
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
很好的题目
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
#include <vector>
using namespace std; const int MAXN = ;
const int MAXM = ; struct Edge
{
int to,next;
bool cut;
}edge[MAXM];
int head[MAXN],tot;
int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];//Belong数组的值是1~block
int Index,top;
int block;
bool Instack[MAXN];
int bridge; void addedge(int u,int v)
{
edge[tot].to = v;edge[tot].next = head[u];edge[tot].cut = false;
head[u] = tot++;
}
void Tarjan(int u,int pre)
{
int v;
Low[u] = DFN[u] = ++Index;
Stack[top++] = u;
Instack[u] = true;
for(int i = head[u];i != -;i = edge[i].next)
{
v = edge[i].to;
if( v == pre )continue;
if( !DFN[v] )
{
Tarjan(v,u);
if(Low[u] > Low[v])Low[u] = Low[v];
if(Low[v] > Low[u])
{
bridge++;
edge[i].cut = true;
edge[i^].cut = true;
}
}
else if(Instack[v] && Low[u] > DFN[v])
Low[u] = DFN[v];
}
if(Low[u] == DFN[u])
{
block++;
do
{
v = Stack[--top];
Instack[v] = false;
Belong[v] = block;
}
while( v != u );
}
}
void init()
{
tot = ;
memset(head,-,sizeof(head));
} vector<int>vec[MAXN];
int father[MAXN];
int dep[MAXN];
int a[MAXN];
void lca_bfs(int root)
{
memset(dep,-,sizeof(dep));
dep[root] = ;
a[root] = ;//桥的标记,标记桥的一个点
father[root] = -;
queue<int>q;
q.push(root);
while(!q.empty())
{
int tmp = q.front();
q.pop();
for(int i = ;i < vec[tmp].size();i++)
{
int v = vec[tmp][i];
if(dep[v]!=-)continue;
dep[v] = dep[tmp]+;
a[v] = ;
father[v] = tmp;
q.push(v);
}
}
}
int ans;
void lca(int u,int v)
{
if(dep[u]>dep[v])swap(u,v);
while(dep[u]<dep[v])
{
if(a[v])
{
ans--;
a[v] = ;
}
v = father[v];
}
while(u != v)
{
if(a[u])
{
ans--;
a[u] = ;
}
if(a[v])
{
ans--;
a[v] = ;
}
u = father[u];
v = father[v];
}
}
void solve(int N)
{
memset(DFN,,sizeof(DFN));
memset(Instack,false,sizeof(Instack));
Index = top = block = ;
Tarjan(,);
for(int i = ;i <= block;i++)
vec[i].clear();
for(int u = ;u <= N;u++)
for(int i = head[u];i != -;i = edge[i].next)
if(edge[i].cut)
{
int v = edge[i].to;
vec[Belong[u]].push_back(Belong[v]);
vec[Belong[v]].push_back(Belong[u]);
}
lca_bfs();
ans = block - ;
int Q;
int u,v;
scanf("%d",&Q);
while(Q--)
{
scanf("%d%d",&u,&v);
lca(Belong[u],Belong[v]);
printf("%d\n",ans);
}
printf("\n");
}
int main()
{
int n,m;
int u,v;
int iCase = ;
while(scanf("%d%d",&n,&m)==)
{
iCase++;
if(n== && m == )break;
init();
while(m--)
{
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
printf("Case %d:\n",iCase);
solve(n);
}
return ;
}
POJ 3694 Network (求桥,边双连通分支缩点,lca)的更多相关文章
- POJ 3694 Network(并查集缩点 + 朴素的LCA + 无向图求桥)题解
题意:给你一个无向图,有q次操作,每次连接两个点,问你每次操作后有几个桥 思路:我们先用tarjan求出所有的桥,同时我们可以用并查集缩点,fa表示缩点后的编号,还要记录每个节点父节点pre.我们知道 ...
- poj 3694 无向图求桥+lca
题意抽象为: 给一个无向图和一些询问 对于每一次询问: 每次询问都会在图上增加一条边 对于每一次询问输出此时图上桥的个数. 桥的定义:删除该边后原图变为多个连通块. 数据规模:点数N(1 ≤ N ≤ ...
- POJ 3694 Network ——(桥 + LCA)
题意:给n个点和m条边,再给出q条边,问每次加一条边以后剩下多少桥. 分析:这题是结合了LCA和dfn的妙用._dfn数组和dfn的意义不一样,并非访问的时间戳,_dfn表示的是被访问的顺序,而且是多 ...
- 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 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 【Tarjan】+【LCA】
<题目链接> 题目大意: 给一个无向图,该图只有一个连通分量.然后查询q次,q < 1000, 求每次查询就增加一条边,求剩余桥的个数. 解题分析: 普通的做法就是在每加一条边后,都 ...
- POJ 3694 无向图的桥
Network Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 10404 Accepted: 3873 Descript ...
- kuangbin专题 专题九 连通图 POJ 3694 Network
题目链接:https://vjudge.net/problem/POJ-3694 题目:给定一个连通图,求桥的个数,每次查询,加入一条边,问加入这条边后还有多少个桥. 思路:tarjan + 并查集 ...
随机推荐
- qemu中device和driver的区别 使用9p文件系统
qemu配置中经常会出现-driver/-device的选项,可以理解成-driver是后端设备,即一个实际的物理的磁盘:device是把这块磁盘插入到虚机中的pci控制器中. 这样的话,虚机也能看到 ...
- Nginx出现500错误解决办法
查看错误日志D:\nginx\logs\error.log 得知:Nginx配置文件中会将路径中的 \t 默认转义成 空格 改为双斜杠就可以了
- MyBatis 基本演示
主配置文件 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration P ...
- [bzoj1033] [ZJOI2008]杀蚂蚁antbuster
Description 最近,佳佳迷上了一款好玩的小游戏:antbuster.游戏规则非常简单:在一张地图上,左上角是蚂蚁窝,右下角是蛋糕,蚂蚁会源源不断地从窝里爬出来,试图把蛋糕搬回蚂蚁窝.而你的任 ...
- 真·APIO2018滚粗记
有人说只有大佬才会说滚粗啊爆零啊…… 然而我真滚粗真爆零啊…… D1: 听课,然后夏眠. 咦折纸……哦好吧太神仙了. 咦AI……好妙啊好妙啊. 咦二分……哇还有wqs二分这种神奇操作,学学学. (我是 ...
- JAVA输出最大值和最小值
public class MaxMin{ public static void main(String[] args) { int[] arr = new int[6]; Scanner input ...
- Data_Structure01-绪论作业!
一.作业题目 仿照三元组或复数的抽象数据类型写出有理数抽象数据类型的描述 (有理数是其分子.分母均为整数且分母不为零的分数). 有理数基本运算: 构造有理数T,元素e1,e2分别被赋以分子.分母值 销 ...
- 快速了解Android重要机制
转自 http://www.jianshu.com/p/5f6d79323923 一.Android系统底层研究 关于底层的知识点不是在一篇文章中能讲解清楚,参见本人的Android底层研究系列,不断 ...
- [模板]大步小步算法——BSGS算法
大步小步算法用于解决:已知A, B, C,求X使得 A^x = B (mod C) 成立. 我们令x = im - j | m = ceil(sqrt(C)), i = [1, m], j = [0, ...
- VC版本与VS版本 对照表
Microsoft Visual Studio 6.0 VC6.0 Microsoft Visual Studio .NET 2002: VC7.0 ...