无向连通图求割边+缩点+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 题目描述: 给出一个无向连通图,加入一系列边指定的后,问还剩下多少个桥? 解题思路: 先求出图的双连通分支,然后缩点重新建图,加入一个指定的边后,求出这条 ...
随机推荐
- [转自Kevins的天空 http://rootsec.cn]rad studio 2007 up3方法
rad studio 2007 网络下载点: http://bbs.hnhyxy.com/bcb/CodeGear.RAD.Studio.2007.rar http://andy.jgknet.de/ ...
- go access database demo
package main import ( "database/sql" "fmt" _ "github.com/lib/pq" " ...
- final关键字+const关键字
final关键字 1.如果我们希望某个类不被其它的类来继承(可能因为安全考虑),可以使用final. 例题 <? final class A{} class B extends A{};//会报 ...
- nginx https
默认情况下ssl模块并未被安装,如果要使用该模块则需要在编译时指定–with-http_ssl_module参数,安装模块依赖于OpenSSL库和一些引用文件,通常这些文件并不在同一个软件包中.通常这 ...
- Qt拖拽界面 (*.ui) 缩放问题及解决办法(在最顶层放一个Layout)
问题 使用Qt Designer 设计的界面,在缩放的时候不能随着主窗口一起缩放. 解决办法 之前遇到这个问题的时候,都是直接重写resizeEvent接口来实现的,在自动生成的Ui_Widget或U ...
- C/C++ 判断主机字节存储序列
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA0oAAADFCAIAAADltpUqAAAgAElEQVR4nOyd65XyvA6FqYASKIEWqI
- oracle 表查询二
1.使用逻辑操作符号问题:查询工资高于500或者是岗位为manager的雇员,同时还要满足他们的姓名首字母为大写的J?select * from emp where (sal > 500 or ...
- iOS NSFileManager
今天,用到了文件的管理,发现自己又忘得差不多了.屋里有个苍蝇,老是在眼前晃来晃去,好是烦人. 用到了两个地方: 1. 创建文件夹: 2. 移动文件 功能还有很多,今天先总结两个! 1. 创建文件夹: ...
- line-block代替float布局;
line-block代替float布局: 我们先看看float的一些特性(特征) 当我们改变浏览器的大小会出现这样的效果: 或则这样: 有时候,我们希望,以第一排最高的元素为换行基准时,我们就可以使用 ...
- 使用Aspose.Cell控件实现Excel高难度报表的生成(三)
在之前几篇文章中,介绍了关于Apsose.cell这个强大的Excel操作控件的使用,相关文章如下: 使用Aspose.Cell控件实现Excel高难度报表的生成(一) 使用Aspose.Cell控件 ...