Network
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 7082   Accepted: 2555

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次询问,每次询问u和v,代表把u和v连接之后此时的图还有多少个桥,(加上的边不在去掉)
分析:如果每次询问加入边之后都进行一次tarjan则会超时,可以先按照桥缩点成一棵树,原来的桥是现在的树的边,每次加入一条边<u,v>之后,把u和v进行LCA,标记一下此时有多少路径被标记,则此时的桥的个数是num-sum;
#include"cstdio"
#include"cstring"
#include"cstdlib"
#include"cmath"
#include"string"
#include"map"
#include"cstring"
#include"iostream"
#include"algorithm"
#include"queue"
#include"stack"
#define inf 0x3f3f3f3f
#define M 100009
#define eps 1e-8
#define INT int
using namespace std;
struct node
{
int u,v,next;
}edge[M*10],e[M*10];
stack<int>q;
int t,head[M],dfn[M],low[M],indx,cut[M*10],num,cnt,belong[M],use[M],suo[M],mark[M*10],pre[M],pp[M],ranks[M],ans;
void init()
{
t=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v)
{
edge[t].u=u;
edge[t].v=v;
edge[t].next=head[u];
head[u]=t++;
}
void tarjan(int u,int id)//求桥
{
dfn[u]=low[u]=++indx;
q.push(u);
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(id==(i^1))continue;
if(!dfn[v])
{
tarjan(v,i);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u])
{
cut[++num]=i;
mark[i]=mark[i^1]=1;//存桥的编号,且把其进行标记
} }
else
low[u]=min(low[u],dfn[v]);
}
}
void slove(int n)
{
num=indx=0;
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(cut,0,sizeof(cut));
memset(mark,0,sizeof(mark));
for(int i=1;i<=n;i++)
{
if(!dfn[i])
tarjan(i,-1);
}
return ;
}
void dfs(int u,int tep)
{
use[u]=1;
suo[u]=tep;
for(int i=head[u];~i;i=edge[i].next)
{
if(mark[i])continue;
int v=edge[i].v;
if(!use[v])
dfs(v,tep);
}
}
void DFS(int u,int fa)
{
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(fa==v)continue;
pre[v]=u;
ranks[v]=ranks[u]+1;
DFS(v,u);
}
}
void LCA(int u,int v)
{
while(u!=v)
{
if(ranks[u]>ranks[v])
{
if(!pp[u])
{
ans++;
pp[u]=1;
}
u=pre[u];
}
else
{
if(!pp[v])
{
pp[v]=1;
ans++;
}
v=pre[v];
}
} }
void litter(int n)
{
cnt=0;
memset(suo,0,sizeof(suo));
memset(use,0,sizeof(use));
for(int i=1;i<=num;i++)//缩点
{
int u=edge[cut[i]].u;
if(!suo[u])
{
dfs(u,++cnt);
}
int v=edge[cut[i]].v;
if(!suo[v])
dfs(v,++cnt);
e[i].u=u;
e[i].v=v;
}
// for(int i=1;i<=n;i++)
//printf("%d %d\n",i,suo[i]);
init();
for(int i=1;i<=num;i++)
{
int u=e[i].u;
int v=e[i].v;
add(suo[u],suo[v]);
add(suo[v],suo[u]);
}//把缩点后的图建成一棵树
memset(pre,-1,sizeof(pre));
ranks[1]=1;
DFS(1,1);
int Q;
cin>>Q;
int sum=0;
memset(pp,0,sizeof(pp));
while(Q--)
{
int a,b;
scanf("%d%d",&a,&b);
ans=0;
LCA(suo[a],suo[b]);
sum+=ans;
printf("%d\n",num-sum);
}
printf("\n"); }
int main()
{
int n,m,a,b,kk=1;
while(scanf("%d%d",&n,&m),n||m)
{
init();
for(int i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
slove(n);
printf("Case %d:\n",kk++);
litter(n); }
return 0;
}
												

无向连通图求割边+缩点+LCA的更多相关文章

  1. ZOJ 2588 Burning Bridges(无向连通图求割边)

    题目地址:ZOJ 2588 由于数组开小了而TLE了..这题就是一个求无向连通图最小割边.仅仅要推断dfn[u]是否<low[v],由于low指的当前所能回到的祖先的最小标号,增加low[v]大 ...

  2. 无向连通图求割边(桥)hdu4738,hdu3849

    点击打开链接 题目链接:   hdu 4738 题目大意:   曹操有N个岛,这些岛用M座桥连接起来 每座桥有士兵把守(也可能没有) 周瑜想让这N个岛不连通,但只能炸掉一座桥 并且炸掉一座桥需要派出不 ...

  3. ZOJ2588:Burning Bridges(无向连通图求割边)

    题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1588 吐下槽,不得不说ZOJ好坑,模版题做了一个多小时. 题意:*    ...

  4. ZOJ 2588 Burning Bridges(求含重边的无向连通图的割边) - from lanshui_Yang

    Burning Bridges Time Limit: 5 Seconds Memory Limit: 32768 KB Ferry Kingdom is a nice little country ...

  5. poj3694+hdu2460 求桥+缩点+LCA/tarjan

    这个题使我更深理解了TARJAN算法,题意:无向图,每添加一条边后文桥的数量,三种解法:(按时间顺序),1,暴力,每每求桥,听说这样能过,我没过,用的hash判重,这次有俩个参数(n->10w, ...

  6. 无向连通图求割点(tarjan算法去掉改割点剩下的联通分量数目)

    poj2117 Electricity Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 3603   Accepted: 12 ...

  7. POJ1523:SPF(无向连通图求割点)

    题目:http://poj.org/problem?id=1523 题目解析: 注意题目输入输入,防止PE,题目就是求割点,并问割点将这个连通图分成了几个子图,算是模版题吧. #include < ...

  8. POJ1144:Network(无向连通图求割点)

    题目:http://poj.org/problem?id=1144 求割点.判断一个点是否是割点有两种判断情况: 如果u为割点,当且仅当满足下面的1条 1.如果u为树根,那么u必须有多于1棵子树 2. ...

  9. Poj 3694 Network (连通图缩点+LCA+并查集)

    题目链接: Poj 3694 Network 题目描述: 给出一个无向连通图,加入一系列边指定的后,问还剩下多少个桥? 解题思路: 先求出图的双连通分支,然后缩点重新建图,加入一个指定的边后,求出这条 ...

随机推荐

  1. Windows Registry

    https://msdn.microsoft.com/en-us/library/windows/desktop/ms724871(v=vs.85).aspx https://msdn.microso ...

  2. Raft

    http://thesecretlivesofdata.com/raft/ https://github.com/coreos/etcd   1 Introduction Consensus algo ...

  3. java 客户端获取真实ip地址

    在开发工作中,我们常常需要获取客户端的IP.一般获取客户端的IP地址的方法是:request.getRemoteAddr();但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实 ...

  4. [转]C#之反射

    前言 之所以要写这篇关于C#反射的随笔,起因有两个:   第一个是自己开发的网站需要用到   其次就是没看到这方面比较好的文章. 所以下定决心自己写一篇,废话不多说开始进入正题. 前期准备 在VS20 ...

  5. Bluetooth L2CAP介绍

    目录 1. 通用操作 1. L2CAP Channel 2. 设备间操作 3. 层间操作 4. 操作模式 2. 数据包格式(Data Packet Format) 1. B-Frame 2. G-Fr ...

  6. PHP 日期比较

    $temptime = mktime(8,2,12,4,4,2014);$dt1 = date("Y-m-d",time());$dt2 = date("Y-m-d&qu ...

  7. grep与find

    grep命令可以指定文件中搜索特定的内容,并将含有这些内容的行标准输出.grep全称是Global Regular Expression Print -c:只输出匹配行的计数.-I:不区分大小写(只适 ...

  8. LightOj1190 - Sleepwalking(判断点与多边形的位置关系--射线法模板)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1190 题意:给你一个多边形含有n个点:然后又m个查询,每次判断点(x, y)是否在多边 ...

  9. Theano学习笔记:Theano的艰辛安装体验

    http://www.cnblogs.com/hanahimi/p/4127026.html

  10. android开发经验

    1.选好"车轮" 一个项目的开发,我们不可能一切从0做起,如果真是这样,那同样要哭瞎.因此,善于借用已经做好的 "车轮" 非常重要,如: 网络访问框架:okht ...