[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)的更多相关文章

  1. 【BZOJ4784】[ZJOI2017]仙人掌(Tarjan,动态规划)

    [BZOJ4784][ZJOI2017]仙人掌(Tarjan,动态规划) 题面 BZOJ 洛谷 题解 显然如果原图不是仙人掌就无解. 如果原图是仙人掌,显然就是把环上的边给去掉,变成若干森林连边成为仙 ...

  2. 【BZOJ1093】[ZJOI2007]最大半联通子图(Tarjan,动态规划)

    [BZOJ1093][ZJOI2007]最大半联通子图(Tarjan,动态规划) 题面 BZOJ 洛谷 洛谷的讨论里面有一个好看得多的题面 题解 显然强连通分量对于题目是没有任何影响的,直接缩点就好了 ...

  3. 【洛谷5008】逛庭院(Tarjan,贪心)

    [洛谷5008]逛庭院(Tarjan,贪心) 题面 洛谷 题解 如果图是一个\(DAG\),我们可以任意选择若干个不是入度为\(0\)的点,然后把它们按照拓扑序倒序删掉,不难证明这样一定是合法的. 现 ...

  4. POJ 1236 Network of Schools(tarjan算法 + LCA)

    这个题目网上有很多答案,代码也很像,不排除我的.大家的思路应该都是taijan求出割边,然后找两个点的LCA(最近公共祖先),这两个点和LCA以及其他点构成了一个环,我们判断这个环上的割边有几条,我们 ...

  5. 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 ...

  6. HDU-3072-IntelligenceSystem(tarjan,贪心)

    链接:https://vjudge.net/problem/HDU-3072 题意: 给你n个点,1个点到另一个点连接花费c,但是如果几个点可以相互可达,则这几个点连通花费为0. 求将整个图连通的最小 ...

  7. [Poj2349]Arctic Network(二分,最小生成树)

    [Poj2349]Arctic Network Description 国防部(DND)要用无线网络连接北部几个哨所.两种不同的通信技术被用于建立网络:每一个哨所有一个无线电收发器,一些哨所将有一个卫 ...

  8. POJ 1144 Network(Tarjan求割点)

    Network Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12707   Accepted: 5835 Descript ...

  9. 【BZOJ1924】【SDOI2010】所驼门王的宝藏(Tarjan,SPFA)

    题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...

随机推荐

  1. JSP Cookies处理

    JSP Cookies处理 Cookies是存储在客户机的文本文件,它们保存了大量轨迹信息.在servlet技术基础上,JSP显然能够提供对HTTP cookies的支持. 通常有三个步骤来识别回头客 ...

  2. Java中高级面试题(1)

    List和Set比较,各自的子类比较 对比一:Arraylist与LinkedList的比较 1.ArrayList是实现了基于动态数组的数据结构,因为地址连续,一旦数据存储好了,查询操作效率会比较高 ...

  3. POJ 1380 Equipment Box (暴力枚举)

    Equipment Box 题目链接: http://acm.hust.edu.cn/vjudge/contest/130510#problem/B Description There is a la ...

  4. MySQL主主模式

    mysql主主复制配置: HOSTNAME IPADDR PORT节点1:my-prod01.oracle.com 192.168.10.97 3306 节点2:my-prod02.oracle.co ...

  5. oracle体系结构基础

    摘自:http://jianshi-dlw.iteye.com/blog/1554892 Oracle的体系结构大体上分为两部分:Instance(实例)和Database(数据库). Instanc ...

  6. codeforces 657C - Bear and Contribution [想法题]

    题目链接: http://codeforces.com/problemset/problem/657/C ----------------------------------------------- ...

  7. 认识DOM(上)

    认识DOM 文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法.DOM 将HTML文档呈现为带有元素.属性和文本的树结构(节点树). 先来看看下面代码 ...

  8. Delphi XE2 之 FireMonkey 入门(22) - 数据绑定: BindingSource、BindingName、FindBinding()、Binding[]

    在窗体上添加 TrackBar1.Edit1.Label1, 然后设置属性(可在设计时): procedure TForm1.FormCreate(Sender: TObject); begin   ...

  9. 四种方法给Vmware虚拟机清理瘦身

    随着VMware虚拟机使用时间的增长,其所占用的空间也越来越大,本文来说说怎么给VMware虚拟机占用的空间进行瘦身. **方法一:VMware自带的清理磁盘 **这个方法是VMware自带,具有普适 ...

  10. 接口自动化之ddt

    接口自动化会用到数据驱动模式,也就是一个ddt模块 目录 1.环境准备 2.调用时标准格式 3.应用(结合excle来传值) 1.环境准备 首先,需要安装ddt模块 pip install ddt 2 ...