HDU2460-Network
题目
给一个\(n\)个点\(m\)条边的无向连通图,\(Q\)次往图中加边,每次加边后问图中的桥有多少个。(加边后边留着)。
\(n\le 10^5,m\le 2\times 10^5,Q\le 10^5\)。
分析
容易发现一条边为桥当且仅当它不在任意一个环中。
于是我们对最开始的图先得到它的生成树,然后把剩下的边加进去,加边的时候把树上两点路径上的点都标记为不是桥。每次询问的时候一样操作。这个东西可以方便地用树链剖分和线段树维护。
时间复杂度为\(O((m-n+Q)\log ^2n)\)。
代码
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
#define M(x) memset(x,0,sizeof x)
using namespace std;
int read() {
int x=0,f=1;
char c=getchar();
for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
for (;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
const int maxn=1e5+1;
const int maxj=17;
const int maxm=2e5+1;
typedef pair<int,int> Pair;
Pair bian[maxm];
int n,m;
namespace uns {
int f[maxn];
void clear(int n) {for (int i=1;i<=n;++i) f[i]=i;}
int find(int x) {return f[x]==x?x:f[x]=find(f[x]);}
}
namespace sgt {
int t[maxn<<2];
bool clr[maxn<<2];
void init(int x,int l,int r) {
clr[x]=false;
if (l==r) {
t[x]=(l!=1);
return;
}
int mid=(l+r)>>1;
init(x<<1,l,mid),init(x<<1|1,mid+1,r);
t[x]=t[x<<1]+t[x<<1|1];
}
void pushdown(int x) {
if (!clr[x]) return;
t[x<<1]=t[x<<1|1]=0;
clr[x<<1]=clr[x<<1|1]=true;
clr[x]=false;
}
void clear(int x,int L,int R,int l,int r) {
if (L==l && R==r) {
t[x]=0;
clr[x]=true;
return;
}
pushdown(x);
int mid=(L+R)>>1;
if (r<=mid) clear(x<<1,L,mid,l,r); else
if (l>mid) clear(x<<1|1,mid+1,R,l,r); else
clear(x<<1,L,mid,l,mid),clear(x<<1|1,mid+1,R,mid+1,r);
t[x]=t[x<<1]+t[x<<1|1];
}
void clear(int l,int r) {
clear(1,1,n,l,r);
}
}
namespace tree {
vector<int> g[maxn];
int f[maxn][maxj],dep[maxn],size[maxn],top[maxn],son[maxn];
int first[maxn],second[maxn],dfx;
void add(int x,int y) {g[x].push_back(y);}
void clear(int n) {
M(f),M(dep),M(size),M(top),M(son),M(first),M(second),dfx=0;
for (int i=1;i<=n;++i) g[i].clear();
}
int dfs(int x,int fa) {
f[x][0]=fa;
dep[x]=dep[fa]+1;
int &sz=size[x]=1,&sn=son[x]=0;
for (int v:g[x]) if (v!=fa) {
sz+=dfs(v,x);
if (size[v]>size[sn]) sn=v;
}
}
void Top(int x,int fa,int tp) {
first[x]=++dfx;
top[x]=tp;
if (son[x]) Top(son[x],x,tp);
for (int v:g[x]) if (v!=son[x] && v!=fa) Top(v,x,v);
second[x]=dfx;
}
void run() {
for (int j=1;j<maxj;++j) for (int i=1;i<=n;++i) f[i][j]=f[f[i][j-1]][j-1];
}
int lca(int x,int y) {
if (dep[x]<dep[y]) swap(x,y);
for (int j=maxj-1;j>=0;--j) if (dep[f[x][j]]>=dep[y]) x=f[x][j];
if (x==y) return x;
for (int j=maxj-1;j>=0;--j) if (f[x][j]!=f[y][j]) x=f[x][j],y=f[y][j];
return f[x][0];
}
void work(int x,int l) {
for (int y=top[x];dep[y]>dep[l];y=top[x=f[y][0]]) {
sgt::clear(first[y],first[x]);
}
if (dep[x]>dep[l]) sgt::clear(first[l]+1,first[x]);
}
int deal(int x,int y) {
if (dep[x]>dep[y]) swap(x,y);
int l=lca(x,y);
x==l?work(y,x):work(x,l),work(y,l);
return sgt::t[1];
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
#endif
int cases=0;
while (true) {
n=read(),m=read();
if (!n && !m) break;
printf("Case %d:\n",++cases);
int wat=0;
uns::clear(n);
tree::clear(n);
for (int i=1;i<=m;++i) {
int x=read(),y=read();
int fx=uns::find(x),fy=uns::find(y);
if (fx!=fy) tree::add(x,y),tree::add(y,x),uns::f[fx]=fy; else bian[++wat]=make_pair(x,y);
}
tree::dfs(1,1);
tree::Top(1,1,1);
tree::run();
sgt::init(1,1,n);
for (int i=1;i<=wat;++i) {
int x=bian[i].first,y=bian[i].second;
tree::deal(x,y);
}
int q=read();
while (q--) {
int x=read(),y=read();
int ans=tree::deal(x,y);
printf("%d\n",ans);
}
puts("");
}
return 0;
}
HDU2460-Network的更多相关文章
- [hdu2460]network(依次连边并询问图中割边数量) tarjan边双联通分量+lca
题意: 给定一个n个点m条边的无向图,q个操作,每个操作给(x,y)连边并询问此时图中的割边有多少条.(连上的边会一直存在) n<=1e5,m<=2*10^5,q<=1e3,多组数据 ...
- Tarjan求割点和桥
by szTom 前置知识 邻接表存储及遍历图 tarjan求强连通分量 割点 割点的定义 在一个无向图中,如果有一个顶点集合,删除这个顶点集合以及这个集合中所有顶点相关联的边以后,图的连通分量增多, ...
- Recurrent Neural Network系列1--RNN(循环神经网络)概述
作者:zhbzz2007 出处:http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明.谢谢! 本文翻译自 RECURRENT NEURAL NETWORKS T ...
- 创建 OVS flat network - 每天5分钟玩转 OpenStack(134)
上一节完成了 flat 的配置工作,今天创建 OVS flat network.Admin -> Networks,点击 "Create Network" 按钮. 显示创建页 ...
- 在 ML2 中配置 OVS flat network - 每天5分钟玩转 OpenStack(133)
前面讨论了 OVS local network,今天开始学习 flat network. flat network 是不带 tag 的网络,宿主机的物理网卡通过网桥与 flat network 连接, ...
- OVS local network 连通性分析 - 每天5分钟玩转 OpenStack(132)
前面已经创建了两个 OVS local network,今天详细分析它们之间的连通性. launch 新的 instance "cirros-vm3",网络选择 second_lo ...
- 再部署一个 instance 和 Local Network - 每天5分钟玩转 OpenStack(131)
上一节部署了 cirros-vm1 到 first_local_net,今天我们将再部署 cirros-vm2 到同一网络,并创建 second_local_net. 连接第二个 instance 到 ...
- 创建 OVS Local Network - 每天5分钟玩转 OpenStack(129)
上一节我们完成了 OVS 的准备工作,本节从最基础的 local network 开始学习.local network 不会与宿主机的任何物理网卡连接,流量只被限制在宿主机内,同时也不关联任何的 VL ...
- Configure a bridged network interface for KVM using RHEL 5.4 or later?
environment Red Hat Enterprise Linux 5.4 or later Red Hat Enterprise Linux 6.0 or later KVM virtual ...
- BZOJ 1146: [CTSC2008]网络管理Network [树上带修改主席树]
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 3522 Solved: 1041[Submi ...
随机推荐
- 20145226夏艺华 《Java程序设计》预备作业3
安装虚拟机 上学期开学的时候就安装了Linux虚拟机,由于我的是Mac OS,所以和windows下的安装有所不同. 我使用的是VirtualBoxVM虚拟机,稳定性还不错,需要的同学可以从https ...
- Ruby 配置vimrc
https://ruby-china.org/topics/19315 mv ~/Downloads/vim-distinguished-develop/colors/*.vim ~/.vim/col ...
- BZOJ4049][CERC2014]Mountainous landscape-[线段树+凸包+二分]
Description 现在在平面上给你一条折线P1P2P3...Pn. x坐标是严格单调递增的.对于每一段折线PiPi+1,请你找一个最小的j,使得j>i且走在PiPi+1的人能看到折线PjP ...
- day5 页面布局
1.主站 <div class='pg-header'> <div style='width:980px;margin:0 auto;'> 内容自动居中 </div> ...
- 拼多多商品id怎么查看 拼多多店铺ID怎样看
网上开店平台有很多编号.id等可以区分商品和店铺的标志,拼多多有店铺id也有商品id,这是两个不同的概念,店铺id进入到拼多多店铺即可查询,拼多多商品id怎么查看 拼多多店铺ID怎样看,那么拼多多商品 ...
- 【转载】IntelliJ IDEA 2017常用快捷键
IntelliJ IDEA 是一款致力于提供给开发工程师沉浸式编程体验的IDE工具,所以在其中提供了很多方便高效的快捷键,一旦熟练掌握,整个开发的效率和体验将大大提升.本文就按照笔者自己日常开发时的使 ...
- PHPCMS的产品筛选功能
如下图所示功能: 首先,用下面这些代码替换掉phpcms/libs/functions/extention.func.php的内容 <?php /** * extention.func.php ...
- MATLAB 笔记
MATLAB的学习 Matlab 主要有5大部分构成,分别是MATLAB语言,桌面工具与开发环境,数学函数库 ,图形系统和应用程序接口.以及众多的专业工具.
- CSS 实用实例
背景颜色 1. 颜色背景 <style type="text/css">body { font-size: 16px;">h1 { font-size: ...
- [C++] Solve "Cannot run program "gdb": Unknown reason" error
In Mac OSX, The Issue Image: 1. Build the project on Eclipse successfully. 2. Run gdb on command lin ...