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 + 并查集 ...
随机推荐
- 搭建 MongoDB分片(sharding) / 分区 / 集群环境
1. 安装 MongoDB 三台机器 关闭防火墙 systemctl stop firewalld.service 192.168.252.121 192.168.252.122 192.168.25 ...
- CentOS修改IP地址
一.CentOS 修改IP地址修改对应网卡的IP地址的配置文件 # vi /etc/sysconfig/network-scripts/ifcfg-eth0 电信 # vi /etc/syscon ...
- shell之进程
ps System V 风格 - -elF -ef -eF BSD a所有跟终端有关的进程 ...
- MYSQL 简单的建库操作代码
一.查询所有数据库 代码:show databases; 成功后如下图: 二.建立一个数据库 代码:create database test3: 成功后如下图: 三.连接数据库 代码:use test ...
- POJ 1039 Pipe | 线段相交
题目: 给一个管子,有很多转弯处,问从管口的射线射进去最长能射到多远 题解: 根据黑书,可以证明的是这条光线一定经过了一个上顶点和下顶点 所以我们枚举每对上下顶点就可以了 #include<cs ...
- The UVALIVE 7716 二维区间第k小
The UVALIVE 7716 二维区间第k小 /** 题意:给一个n * n的矩阵,有q个查询 每次查询r,c,s,k表示已(r,c)为右上角 大小为s的正方形中 第k小的元素 n <= 2 ...
- Codeforces Round #359 (Div. 2) B
B. Little Robber Girl's Zoo time limit per test 2 seconds memory limit per test 256 megabytes input ...
- 【Error】Python:UnicodeDecodeError: ‘XXX' codec can't decode bytes in position... 解决方法
错误信息: UnicodeDecodeError: ‘XXX' codec can't decode bytes in position 2-5: illegal multibyte sequence ...
- mysql5.6免安装配置(菜鸟版)
mysql5.6免安装配置 MySQL5.6.13安装步骤(Windows7 32位) 1. 下载MySQL Community Server 5.6.13 2. 解压MySQL压缩包 将以下载的My ...
- [fjwc2015]Screen [从hzw神犇那里扒来的题]
[题目描述] 码农有一块超新星屏幕,它有N个像素点,每个像素点有亮度和灰度两个参数,记为I和H, 范围都是0~32000. 一天,码农突发奇想,想知道哪个点比较容易亮瞎眼睛.为此,他定义了一个瞎眼指数 ...