[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是这个家族的领袖,外人也称其为"所驼门王". ...
随机推荐
- CG-CTF | 综合题2
查源码发现一个文件读取:http://cms.nuptzj.cn/about.php?file=sm.txt,用它把能找到的php都读取下来 <?php if (!isset($_COOKIE[ ...
- bytesToSize
export function bytesToSize(bytes){ if (bytes === 0) return '0 B' let k = 1024, // or 1000 sizes = [ ...
- 【30分钟学完】canvas动画|游戏基础(1):理论先行
前言 本文虽说是基础教程,但这是相对动画/游戏领域来说,在前端领域算是中级教程了,不适合前端小白或萌新.阅读前请确保自己对前端三大件(JavaScript+CSS+HTML)的基础已经十分熟悉,而且有 ...
- <foreach></foreach>标签
当传入参数为数组或者集合时需要通过<foreach></foreach>标签进行遍历 1.首先在po类中定义一个集合或者数组 比如 private List<Intege ...
- Oracle JET(一)Oracle JET介绍
Oracle JET (Oracle Javascript Extension Toolkit)是一款 Oracle 的 JavaScript 拓展工具包.简单来说 Oracle JET 是一个一堆好 ...
- ORACLE DG在线日志修改
ORACLE DG在线日志修改 SQL>select SEQUENCE#,first_time,next_time,APPLIED, THREAD# from v$archived_log or ...
- KindEditor上传图片一直提示undefined
图片已经上传成功了,但是就是不在文本编辑器里显示图片,一直弹出undefined 返回的JSON都对呀!这是官网说的返回值: //成功时 { "error" : 0, " ...
- R语言CSV文件
R语言CSV文件 在R语言中,我们可以从存储在R环境外部的文件读取数据.还可以将数据写入由操作系统存储和访问的文件. R可以读取和写入各种文件格式,如:csv,excel,xml等. 在本章中,我们将 ...
- 关于staticmethod() 函数
说实话,我就不知这个是干什么的. 菜鸟教程写的无需实例化, 自己可以调用自己. 在同一个类面我使用到了 因为一个类了, 我可能会方法间互相调用. 类中间使用.不加这个,就会报错.无法识别这个 orig ...
- 16/7/8_PHP-字符串介绍
不知道为什么慕课网还这个都要介绍.不过还是一个新的知识点. PHP开发中,我们遇到最多的可能就是字符串. 字符串变量用于包含字符串的值. 一个字符串 通过下面的3种方法来定义: 1.单引号2.双引号3 ...