无向连通图求割边+缩点+LCA
| 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的更多相关文章
- ZOJ 2588 Burning Bridges(无向连通图求割边)
题目地址:ZOJ 2588 由于数组开小了而TLE了..这题就是一个求无向连通图最小割边.仅仅要推断dfn[u]是否<low[v],由于low指的当前所能回到的祖先的最小标号,增加low[v]大 ...
- 无向连通图求割边(桥)hdu4738,hdu3849
点击打开链接 题目链接: hdu 4738 题目大意: 曹操有N个岛,这些岛用M座桥连接起来 每座桥有士兵把守(也可能没有) 周瑜想让这N个岛不连通,但只能炸掉一座桥 并且炸掉一座桥需要派出不 ...
- ZOJ2588:Burning Bridges(无向连通图求割边)
题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1588 吐下槽,不得不说ZOJ好坑,模版题做了一个多小时. 题意:* ...
- ZOJ 2588 Burning Bridges(求含重边的无向连通图的割边) - from lanshui_Yang
Burning Bridges Time Limit: 5 Seconds Memory Limit: 32768 KB Ferry Kingdom is a nice little country ...
- poj3694+hdu2460 求桥+缩点+LCA/tarjan
这个题使我更深理解了TARJAN算法,题意:无向图,每添加一条边后文桥的数量,三种解法:(按时间顺序),1,暴力,每每求桥,听说这样能过,我没过,用的hash判重,这次有俩个参数(n->10w, ...
- 无向连通图求割点(tarjan算法去掉改割点剩下的联通分量数目)
poj2117 Electricity Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 3603 Accepted: 12 ...
- POJ1523:SPF(无向连通图求割点)
题目:http://poj.org/problem?id=1523 题目解析: 注意题目输入输入,防止PE,题目就是求割点,并问割点将这个连通图分成了几个子图,算是模版题吧. #include < ...
- POJ1144:Network(无向连通图求割点)
题目:http://poj.org/problem?id=1144 求割点.判断一个点是否是割点有两种判断情况: 如果u为割点,当且仅当满足下面的1条 1.如果u为树根,那么u必须有多于1棵子树 2. ...
- Poj 3694 Network (连通图缩点+LCA+并查集)
题目链接: Poj 3694 Network 题目描述: 给出一个无向连通图,加入一系列边指定的后,问还剩下多少个桥? 解题思路: 先求出图的双连通分支,然后缩点重新建图,加入一个指定的边后,求出这条 ...
随机推荐
- Euler's totient function
https://en.wikipedia.org/wiki/Euler's_totient_function counts the positive integers up to a given in ...
- 【微信开发之问题集锦】redirect_uri 参数错误
问题答案:看看网页授权域名是不是以"http://",是则去掉.(如果网页授权域名都没修改,那就去修改吧,要注意域名不要带"http://"."htt ...
- java effective 读书笔记
java effective 读书笔记 []创建和销毁对象 静态工厂方法 就是“封装了底层 暴露出一个访问接口 ” 门面模式 多参数时 用构建器,就是用个内部类 再让内部类提供构造好的对象 枚举 si ...
- SVM神经网络的术语理解
SVM(Support Vector Machine)翻译成中文是支持向量机, 这里的“机(machine,机器)”实际上是一个算法.而支持向量则是指那些在间隔区边缘的训练样本点[1]. 当初看到这个 ...
- Android高级之第十一讲Hybird开发
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 随着移动端应用平台的兴起,需求和交互方式的多样化,H5开发逐渐在移动端流行起来:常见的移动产品有We ...
- zepto源码--$.map,$.each,$.grep--学习笔记
从相对比较简单的说起: 1.$.grep 获取一个新数组,新数组只包含回调函数中返回 true 的数组项. 调用javascript中数组原生函数filter,对elements进行过滤,保留回调函 ...
- iOS _BSMachError: (os/kern) invalid capability (20)
_BSMachError: (os/kern) invalid capability (20) 解决办法:将info.plist里面的en改为United States 2016-04-18 22:4 ...
- JS-010-覆盖率测试工具 JSCoverage 初识
在日常的 js 脚本语言开发过程中,在开发攻城狮进行日常的单元测试和测试攻城狮日常的测试过程中,js 代码的覆盖率是白盒测试的一个重要的考量标准.前些天,在无意中看到了一个 js 覆盖率测试统计工具 ...
- IN和exists 之间的比较
IN和exists 之间的比较 NOT IN 和 NOT EXISTS之间的比较
- 如何安装sass
1.安装ruby 2. 运行ruby时输入 gem install 及sass安装文件路径. sass安装文件见文件.