题意:给你一个无向连通图,每次加一条边后,问图中桥的数目。

思路:先将图进行双联通缩点,则缩点后图的边就是桥,然后dfs记录节点深度,给出(u,v)使其节点深度先降到同一等级,然后同时降等级直到汇合到同一个点为止。途中直接进行删边处理且桥的数目减少。

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
#define MAXN 100005
struct E
{
int to,next;
}edge[10*MAXN],e[10*MAXN]; int tt,tot,index,cnt,n,m,k;
int h[MAXN],head[MAXN],vis[MAXN],dfn[MAXN],low[MAXN],fa[MAXN],level[MAXN],pre[MAXN],res[MAXN];
bool bridge[MAXN]; void addedge(int u,int v)
{
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++; edge[tot].to=u;
edge[tot].next=head[v];
head[v]=tot++;
}
void adde(int u,int v)
{
e[tt].to=v;
e[tt].next=h[u];
h[u]=tt++;
}
int find(int x)
{
if(x!=fa[x])
fa[x]=find(fa[x]);
return fa[x];
}
void tarjan(int u,int f)
{
int i,v;
vis[u]=1;
dfn[u]=low[u]=++index;
for(int i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].to;
if(vis[v]==0)
{
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(dfn[u]<low[v])//判断桥
{
cnt++;
res[cnt]=i;
}
else //合并
{
u=find(u);
v=find(v);
fa[v]=u;
}
}
else if(vis[v]==1&&v!=f)
{
low[u]=min(low[u],dfn[v]);
}
}
vis[u]=2;
}
void lca_dfs(int u,int d)
{
int i,v;
level[u]=d;
vis[u]=1;
for(int i=h[u];i!=-1;i=e[i].next)
{
v=e[i].to;
if(!vis[v])
{
pre[v]=u;
lca_dfs(v,d+1);
}
}
}
void lca(int u,int v)
{
while(level[u]>level[v])
{
if(bridge[u])
{
cnt--;
bridge[u]=0;
}
u=pre[u];
}
while(level[v]>level[u])
{
if(bridge[v])
{
cnt--;
bridge[v]=0;
}
v=pre[v];
}
while(u!=v)
{
if(bridge[u])
{
cnt--;
bridge[u]=0;
}
if(bridge[v])
{
cnt--;
bridge[v]=0;
}
u=pre[u];
v=pre[v];
}
}
void Init()
{
memset(h,-1,sizeof(h));
memset(head,-1,sizeof(head));
memset(dfn,0,sizeof(dfn));
memset(vis,0,sizeof(vis));
memset(bridge,false,sizeof(bridge));
memset(level,0,sizeof(level));
tot=tt=index=cnt=0;
for(int i=1;i<=n;i++)
{
fa[i]=i;
}
}
int main()
{
freopen("in.txt","r",stdin);
int t=1;
while(scanf("%d%d",&n,&m)!=EOF,(n||m))
{
Init();
for(int i=0;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
addedge(u,v);
}
for(int i=1;i<=n;i++)
if(!vis[i])
tarjan(i,-1);
int a,b;
for(int u=1;u<=n;u++) //缩点后再构图
{
for(int j=head[u];j!=-1;j=edge[j].next)
{
int v=edge[j].to;
a=find(u);
b=find(v);
if(a!=b)
{
adde(a,b);
}
}
}
memset(vis,0,sizeof(vis));
lca_dfs(fa[1],1);
for(int i=1;i<=cnt;i++)
{
bridge[find(edge[res[i]].to)]=1;
}
printf("Case %d:\n",t++);
scanf("%d",&k);
while(k--)
{
int i,j;
scanf("%d%d",&i,&j);
int x=find(i),y=find(j);
if(x!=y)
{
lca(x,y);
}
printf("%d\n",cnt);
}
printf("\n");
}
return 0;
}

poj 3694双联通缩点+LCA的更多相关文章

  1. hdu 2460 poj 3694 (双联通+LCA)

    在给出的两个点上加一条边,求剩下桥的数量,,不会LCA在线,就用了最普通的,先Tarjan双联通缩点,然后将缩完的图建成一棵树,树的所有边就是桥了,如果在任意两点间加一条边的话,那么从两点到最近公共祖 ...

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

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

  3. 边的双联通+缩点+LCA(HDU3686)

    Traffic Real Time Query System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  4. hdu 4612 双联通缩点+树形dp

    #pragma comment(linker,"/STACK:102400000,102400000")//总是爆栈加上这个就么么哒了 #include<stdio.h> ...

  5. HDU 3686 Traffic Real Time Query System(双连通分量缩点+LCA)(2010 Asia Hangzhou Regional Contest)

    Problem Description City C is really a nightmare of all drivers for its traffic jams. To solve the t ...

  6. POJ 3694——Network——————【连通图,LCA求桥】

    Network Time Limit:5000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Stat ...

  7. Codeforces 1000 组合数可行线段倒dp 边双联通缩点求树直径

    A /*Huyyt*/ #include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) using namespace std ...

  8. 图论-桥/割点/双连通分量/缩点/LCA

    基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个 ...

  9. POJ3694 Network(边双连通分量+缩点+LCA)

    题目大概是给一张图,动态加边动态求割边数. 本想着求出边双连通分量后缩点,然后构成的树用树链剖分+线段树去维护路径上的边数和..好像好难写.. 看了别人的解法,这题有更简单的算法: 在任意两点添边,那 ...

随机推荐

  1. 笔记本电脑连接上WiFi后,弹不出登录界面怎么办?

    以CMCC为例子 步骤: 1 连接成功CMCC之后,打开适配器设置.右击无线网卡,选择属性 2.双击INTERNET协议版本4 3.将DNS改成自动获取,然后确定 4.再确定 5.然后重新断开CMCC ...

  2. DHCP服务的部署和配置

    DHCP介绍: DHCP(动态主机配置协议)是一个局域网网络协议,使用UDP协议工作,主要用途:给局域网络或网络服务供应商自动分配IP地址, DHCP有3个端口,其中UDP67和UDP68为正常的DH ...

  3. [小北De编程手记] Lesson 01 - AutoFramework构建 之 从一个简单的Demo聊起

    写在最前面 这个系列的主旨是要跟大家分享一下关于自动化测试框架的构建的一些心得.这几年,做了一些自动化测试框架以及团队的构建的工作.过程中遇到了很多这样的同学,他们在学习了某一门语言和一些自动化测试的 ...

  4. NO.1-M2

    一,CSS盒模型   1,当父盒子包裹子盒子,且上边线重合时,给子盒子添加margin-top时,子盒子与父盒子的上边线并不能分开,,而是导致,两个盒子同时下来,而是导致,两个盒子同时下来 使两条上边 ...

  5. python之禅 the zen of python

    >>> import this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is ...

  6. 在Entity Framework 中用 Code First 创建新的数据库

    在Entity Framework 中用 Code First 创建新的数据库 (原文链接) 本文将逐步介绍怎样用Code First 创建新数据库,使用在代码中定义类和API中提供的特性(Attri ...

  7. 截屏工具 HyperSnap

    听说Tencent开发了1款截屏工具,叫"snip".确实字体效果不错,但是丫只有for mac的,不知道脑子里怎么想的,该不是直接买了第三方的然后冠了个名儿吧. 那么Windows有没有类似的工具呢 ...

  8. 【Spring】的【bean】管理(XML配置文件)

    Bean实例化的三种方式 说明:通过配置文件创建对象就称为Bean实例化. 第一种:使用类的无参构造创建(重点) 实体类 package com.tyzr.ioc; public class User ...

  9. Python第一行代码

    Python版本:Python 3.6.1 0x01 命令行交互 在交互式环境的提示符>>>下,直接输入代码,按回车,就可以立刻得到代码执行结果.现在,试试输入100+200,看看计 ...

  10. Ubuntu 如何安装Google Chrome浏览器

    1.上Chrome 官网下载http://www.google.cn/chrome/browser/desktop/ 2.保存下载文件到Home路径下(个人习惯) 3.按Ctrl+Alt +T 调出终 ...