[POJ3694]Network(Tarjan,LCA)
[POJ3694]Network
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
题意
给定一张\(N\)个点\(M\)条边的无向连通图,然后执行\(Q\)次操作,每次向图中添加一条边,并且询问当前无向图中“桥”的数量。
核心知识:边双联通分量
先一遍\(tarjan\)把原图中的桥全部标记,然后\(dfs\)把各个边双联通分量建成树。
考虑到每次加边:
1.两端点在同一个边双联通分量中,对答案不造成影响。
2.两端点不在同一个边双联通分量,因为在树中,所以可以形成一个环,两个边双联通分量之间的路径不再是桥,在总答案中减去。
因为本题时间比较宽裕,所以我们暴力往上跳就可以过了,但是还可以用并查集优化,但是没有打出来,下次再填坑吧。。。
边双联通分量的求法
求出无向图中所有的桥,把桥“删除”,无向图会分成若干个联通块,每一个联通块就是一个边双联通分量。求边双联通分量的时间复杂度:\(O(n)\)。
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int read()
{
int x=0,w=1;char ch=getchar();
while(ch>'9'||ch<'0') {if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*w;
}
const int N=100010;
int n,m,q,t,cnt=1,visnum,num,ans,a,b;
int head[2*N],dfn[N],low[N],fa[2*N],x[2*N],y[2*N],deep[2*N];
bool bridge[4*N],vis[N],dcc[N];
struct node{
int to,next;
}edge[8*N];
void add(int x,int y)
{
cnt++;edge[cnt].to=y;edge[cnt].next=head[x];head[x]=cnt;
}
int gfa(int x){if(fa[x]==x)return x;return fa[x]=gfa(fa[x]);}
void tarjan(int k,int last)
{
dfn[k]=low[k]=++visnum;
for(int i=head[k];i;i=edge[i].next)
{
int v=edge[i].to;
if(!dfn[v])
{
tarjan(v,i);low[k]=min(low[k],low[v]);
if(low[v]>dfn[k])
{
bridge[i]=bridge[i^1]=1;ans++;
}
}
else if(i!=(last^1))low[k]=min(low[k],dfn[v]);
}
}
void dfs1(int k)
{
vis[k]=1;fa[k]=num;
for(int i=head[k];i;i=edge[i].next)
{
int v=edge[i].to;if(vis[v]||bridge[i])continue;
dfs1(v);
}
}
void dfs2(int k,int f)
{
for(int i=head[k];i;i=edge[i].next)
{
int v=edge[i].to;if(v==f)continue;
deep[v]=deep[k]+1;fa[v]=k;dcc[v]=1;dfs2(v,k);
}
}
int jump(int xx,int yy)
{
int qwe=0;if(deep[xx]<deep[yy]) swap(xx,yy);
while(deep[xx]>deep[yy])
{
if(dcc[xx]) dcc[xx]=0,qwe++;xx=fa[xx];
}
if(xx==yy)return qwe;
while(xx!=yy)
{
if(dcc[xx]) dcc[xx]=0,qwe++;xx=fa[xx];
if(dcc[yy]) dcc[yy]=0,qwe++;yy=fa[yy];
}
return qwe;
}
int main()
{
while(1)
{
n=read();m=read();if(n==0)break;t++;num=n;
for(int i=1;i<=m;i++)
{
x[i]=read();y[i]=read();
add(x[i],y[i]);add(y[i],x[i]);
}
tarjan(1,0);
for(int i=1;i<=n;i++)
{
if(!vis[i]){num++;fa[num]=num;dfs1(i);}
}
for(int i=1;i<=m;i++)
{
int xx=gfa(x[i]),yy=gfa(y[i]);
if(xx!=yy) add(xx,yy),add(yy,xx);
}
deep[n+1]=1;dfs2(n+1,0);q=read();
printf("Case %d:\n",t);
for(int j=1;j<=q;j++)
{
a=read();b=read();
int xx=fa[a],yy=fa[b];
if(xx!=yy) ans-=jump(xx,yy);printf("%d\n",ans);
}
printf("\n");
}
}
[POJ3694]Network(Tarjan,LCA)的更多相关文章
- 【BZOJ4784】[ZJOI2017]仙人掌(Tarjan,动态规划)
[BZOJ4784][ZJOI2017]仙人掌(Tarjan,动态规划) 题面 BZOJ 洛谷 题解 显然如果原图不是仙人掌就无解. 如果原图是仙人掌,显然就是把环上的边给去掉,变成若干森林连边成为仙 ...
- 【BZOJ1093】[ZJOI2007]最大半联通子图(Tarjan,动态规划)
[BZOJ1093][ZJOI2007]最大半联通子图(Tarjan,动态规划) 题面 BZOJ 洛谷 洛谷的讨论里面有一个好看得多的题面 题解 显然强连通分量对于题目是没有任何影响的,直接缩点就好了 ...
- 【洛谷5008】逛庭院(Tarjan,贪心)
[洛谷5008]逛庭院(Tarjan,贪心) 题面 洛谷 题解 如果图是一个\(DAG\),我们可以任意选择若干个不是入度为\(0\)的点,然后把它们按照拓扑序倒序删掉,不难证明这样一定是合法的. 现 ...
- POJ 1236 Network of Schools(tarjan算法 + LCA)
这个题目网上有很多答案,代码也很像,不排除我的.大家的思路应该都是taijan求出割边,然后找两个点的LCA(最近公共祖先),这两个点和LCA以及其他点构成了一个环,我们判断这个环上的割边有几条,我们 ...
- SPOJ 3978 Distance Query(tarjan求LCA)
The traffic network in a country consists of N cities (labeled with integers from 1 to N) and N-1 ro ...
- HDU-3072-IntelligenceSystem(tarjan,贪心)
链接:https://vjudge.net/problem/HDU-3072 题意: 给你n个点,1个点到另一个点连接花费c,但是如果几个点可以相互可达,则这几个点连通花费为0. 求将整个图连通的最小 ...
- [Poj2349]Arctic Network(二分,最小生成树)
[Poj2349]Arctic Network Description 国防部(DND)要用无线网络连接北部几个哨所.两种不同的通信技术被用于建立网络:每一个哨所有一个无线电收发器,一些哨所将有一个卫 ...
- POJ 1144 Network(Tarjan求割点)
Network Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 12707 Accepted: 5835 Descript ...
- 【BZOJ1924】【SDOI2010】所驼门王的宝藏(Tarjan,SPFA)
题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...
随机推荐
- CodeForces - 474D (dp)
题目:https://vjudge.net/contest/326867#problem/B 题意:有很多个蛋糕,现在你有两种吃蛋糕的吃法,一次吃一个,定为A,一次吃k个定为B,然后问你吃m个蛋糕有多 ...
- SpringBoot项目属性配置-第二章
SpringBoot入门 1. 相信很多人选择Spring Boot主要是考虑到它既能兼顾Spring的强大功能,还能实现快速开发的便捷.我们在Spring Boot使用过程中,最直观的感受就是没有了 ...
- python条件判断之直接加数字
if 后面跟的是条件表达式,条件表达式的结果为True或者False. (1)如果if后面的条件是数字,只要这个数字不是0,python都会把它当做True处理,见下面的例子: if 3: print ...
- php中钩子(hook)的应用示例demo
我们先来回顾下原本的开发流程:产品汪搞出了一堆需求:当用户注册成功后需要发送短信.发送邮件等等:然后聪明机智勇敢的程序猿们就一扑而上:把这些需求转换成代码扔在 用户注册成功 和 跳转到首页 之间: 没 ...
- optistruct线性求解一次二次单元应力位移比较
通过分析比较10mm.5mm.3mm.1mm的网格模型, 网格越细密: 位移与应力均趋于恒定值(收敛): 一次与二次单元的应力区域一致: 一次与二次单元的位移相差11.3%,一次单元的位移小. 所用的 ...
- python twisted异步将数据导入到数据库中
from twisted.enterprise import adbapi from twisted.internet import reactor def creat_conn(): # 数据库基本 ...
- Delphi XE2 之 FireMonkey 入门(26) - 数据绑定: TBindingsList: TBindExprItems
Delphi XE2 之 FireMonkey 入门(26) - 数据绑定: TBindingsList: TBindExprItems 如果要给一对 "源控件" 和 " ...
- oracle 11g 数据库恢复技术 ---01 重做日志
一 redo log Oracle数据库中的三大核心文件分别是数据文件(data file).重做日志(redo log)和控制文件(control file).数据文件保证了数据库的持久性,是保存修 ...
- 【CTS】几个serialno失败项
[问题结论] [Common]SN配置项的问题,只可以'数字与大小写字母' 将配置SN改为字母数字组合,测试全部pass [问题描述] CTS三条失败项 run cts -m CtsTelephony ...
- oracle--表类型