题意:

给定一个n个点m条边的无向图,q个操作,每个操作给(x,y)连边并询问此时图中的割边有多少条。(连上的边会一直存在)

n<=1e5,m<=2*10^5,q<=1e3,多组数据。

题解:

用tarjan求边双连通分量并缩点,缩点后组成一棵树,记录此时割边共有sum条。

连接(x,y),设c[i]为缩点后i所在的新点(边双连通分量),则c[x]-->lca-->c[y]形成一个环,环上的所有边都不再是割边,走一遍并标记,如果遇到没标记过的就sum--。

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std; const int N=,M=,K=;
int n,m,al,bl,sum,num,sl,cnt;
int afirst[N],bfirst[N],fa[N][K],dfn[N],low[N],is[N],c[N],s[N],dep[N];
struct node{
int x,y,tmp,next;
}a[*M],b[*M]; int minn(int x,int y){return x<y ? x:y;} void ins_a(int x,int y)
{
a[++al].x=x;a[al].y=y;a[al].tmp=;
a[al].next=afirst[x];afirst[x]=al;
} void ins_b(int x,int y)
{
b[++bl].x=x;b[bl].y=y;
b[bl].next=bfirst[x];bfirst[x]=bl;
} void tarjan(int x)
{
dfn[x]=low[x]=++num;
s[++sl]=x;
for(int i=afirst[x];i;i=a[i].next)
{
if(a[i].tmp) continue;
a[i].tmp=;
a[i%== ? i-:i+].tmp=;
int y=a[i].y;
if(!dfn[y])
{
tarjan(y);
low[x]=minn(low[x],low[y]);
if(dfn[x]<low[y])
{
sum++;//printf("%d -- > %d\n",x,y);
cnt++;
int z;
while()
{
z=s[sl--];
c[z]=cnt;
if(z==y) break;
}
}
}
else low[x]=minn(low[x],dfn[y]);
}
} void dfs(int x)
{
for(int i=bfirst[x];i;i=b[i].next)
{
int y=b[i].y;
if(y==fa[x][]) continue;
fa[y][]=x;dep[y]=dep[x]+;
dfs(y);
}
} void prepare_lca()
{
memset(fa,,sizeof(fa));
memset(dep,,sizeof(dep));
memset(is,,sizeof(is));
dep[]=;
dfs();
for(int j=;j<=;j++)
for(int i=;i<=n;i++)
fa[i][j]=fa[fa[i][j-]][j-];
} int get_lca(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int i=;i>=;i--)
if(dep[fa[x][i]]>=dep[y]) x=fa[x][i];
if(x==y) return x;
for(int i=;i>=;i--)
{
if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
}
return fa[x][];
} void del(int x,int y,int lca)
{
while(x!=lca)
{
if(!is[x]) sum--;
is[x]=;
x=fa[x][];
}
while(y!=lca)
{
if(!is[y]) sum--;
is[y]=;
y=fa[y][];
}
} int main()
{
freopen("a.in","r",stdin);
int q,x,y,T=;
while()
{
scanf("%d%d",&n,&m);
if(!n && !m) return ;
printf("Case %d:\n",++T);
al=;bl=;sum=;
memset(afirst,,sizeof(afirst));
memset(bfirst,,sizeof(bfirst));
num=;sl=;cnt=;
memset(dfn,,sizeof(dfn));
memset(c,,sizeof(c));
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
ins_a(x,y);ins_a(y,x);
}
for(int i=;i<=n;i++)
{
if(!dfn[i])
{
tarjan(i);
if(sl)
{
cnt++;
for(int i=;i<=sl;i++) c[s[i]]=cnt;
sl=;
}
}
} for(int i=;i<=*m;i++)
{
x=a[i].x,y=a[i].y;
if(c[x]!=c[y]) ins_b(c[x],c[y]);
}
// for(int i=1;i<=bl;i++)
// printf("%d -- > %d\n",b[i].x,b[i].y);
// for(int i=1;i<=n;i++) printf("c [ %d ] = %d\n",i,c[i]);
prepare_lca();
scanf("%d",&q);
for(int i=;i<=q;i++)
{
scanf("%d%d",&x,&y);
x=c[x];y=c[y];
int lca=get_lca(x,y);
del(x,y,lca);
printf("%d\n",sum);
}
printf("\n");
}
return ;
}

[hdu2460]network(依次连边并询问图中割边数量) tarjan边双联通分量+lca的更多相关文章

  1. [J]computer network tarjan边双联通分量+树的直径

    https://odzkskevi.qnssl.com/b660f16d70db1969261cd8b11235ec99?v=1537580031 [2012-2013 ACM Central Reg ...

  2. POJ3694 Network —— 边双联通分量 + 缩点 + LCA + 并查集

    题目链接:https://vjudge.net/problem/POJ-3694 A network administrator manages a large network. The networ ...

  3. 图连通性【tarjan点双连通分量、边双联通分量】【无向图】

    根据 李煜东大牛:图连通性若干拓展问题探讨 ppt学习. 有割点不一定有割边,有割边不一定有割点. 理解low[u]的定义很重要. 1.无向图求割点.点双联通分量: 如果对一条边(x,y),如果low ...

  4. poj 3177 Redundant Paths 求最少添加几条边成为双联通图: tarjan O(E)

    /** problem: http://poj.org/problem?id=3177 tarjan blog: https://blog.csdn.net/reverie_mjp/article/d ...

  5. UML类图中的关系和表示方法

    类图是用来描述程序中的类以及它们之间的关系的,使用类图可以帮助我们简化对系统的理解.在UML类图中比较常见的关系有六种,它们分别是:依赖.关联.聚合.组合.泛化.实现,这六种关系中类之间的紧密程度是依 ...

  6. Ex 3_25 图中每个顶点有一个相关价格..._十一次作业

    (a)首先对有向无环图进行拓扑排序,再按拓扑排序的逆序依次计算每个顶点的cost值,每个顶点的cost值为自身的price值与相邻顶点间的cost值得最小值 (b)求出图中的每一个强连通分量,并把所有 ...

  7. Dijkstra 算法,用于对有权图进行搜索,找出图中两点的最短距离

    Dijkstra 算法,用于对有权图进行搜索,找出图中两点的最短距离,既不是DFS搜索,也不是BFS搜索. 把Dijkstra 算法应用于无权图,或者所有边的权都相等的图,Dijkstra 算法等同于 ...

  8. UML类图中的各种箭头代表的含义(转自:http://www.cnblogs.com/damsoft/archive/2016/10/24/5993602.html)

    1.UML简介Unified Modeling Language (UML)又称统一建模语言或标准建模语言. 简单说就是以图形方式表现模型,根据不同模型进行分类,在UML 2.0中有13种图,以下是他 ...

  9. UML类图中的关系表示

    UML类图中的关系和表示方法 类图是用来描述程序中的类以及它们之间的关系的,使用类图可以帮助我们简化对系统的理解.在UML类图中比较常见的关系有六种,它们分别是:依赖.关联.聚合.组合.泛化.实现,这 ...

随机推荐

  1. Unity3D 入门 - 工作区域介绍 与 入门示例

    一. 工作区域详解 1. Scence视图 (场景设计面板) scence视图简介 : 展示创建的游戏对象, 可以对所有的游戏对象进行 移动, 操作 和 放置; -- 示例 : 创建一个球体, 控制摄 ...

  2. Alpha 冲刺(1/10)

    队名 火箭少男100 组长博客 林燊大哥 作业博客 Alpha 冲鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调各成员之间的工作,对多个目标检测及文字识别模型进行评估.实验,选取较 ...

  3. iOS- Apple零配置网络协议Bonjour的使用?

    1.前言 这段时间为了解决公司App的网络离线需求,做了个Apple推出的零配置网络协议Bonjour的Test,主要是为了解决iOS设备的IP获取,之前是可以使用socket的广播来实现,但是使用A ...

  4. <Android>资源的访问,颜色、字符串、尺寸、XML、DRAWABLES资源分使用

    1.资源的访问 代码中使用Context的getResources()方法得到Resources对象,访问自己定义的资源R.资源文件类型.资源文件名称,访问系统定义的资源android.R. 资源文件 ...

  5. JS中的数组转变成JSON格式字符串的方法

    有一个JS数组,如: var arr = [["projectname1","projectnumber1"],["projectname2" ...

  6. 使用协程(gevent)实现请求

    协程,又称微线程.英文名Coroutine. 协程最大的优势就是协程极高的执行效率.因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就 ...

  7. 【week2】 构建之法 读后感及问题

    上一次读后感涵盖前五章的内容包括个人技术,结对合作,小组项目等.本周作业的燃尽图以及站立会议是关于<构建之法>第六章的内容,所以关于这一章的读后感涵盖在上两篇博客中. 第七章 MSF 介绍 ...

  8. HDU 2114 Calculate S(n)

    http://acm.hdu.edu.cn/showproblem.php?pid=2114 Problem Description Calculate S(n). S(n)=13+23 +33 +. ...

  9. java中多种方式读文件

    转自:http://www.jb51.net/article/16396.htm java中多种方式读文件 一.多种方式读文件内容. 1.按字节读取文件内容 2.按字符读取文件内容 3.按行读取文件内 ...

  10. [OS] 生产者-消费者问题(有限缓冲问题)

    ·最简单的情形--(一个生产者 + 一个消费者 + 一个大小为1的有限缓冲) 首先来分析其中的同步关系: ·必须在生产者放入一个产品之后,消费者才能够从缓冲中取出产品来消费.·只有在消费者从缓冲区中取 ...