POJ3694 Network 边双缩点+LCA+并查集
辣鸡错误:把dfs和ldfs搞混。。。QAQ
题意:给定一个无向图,然后查询q次,求每次查询就在图上增加一条边,求剩余割边的个数。
先把边双缩点,然后预处理出LCA的倍增数组;
然后加边时,从u往上跳,把所有u到LCA(u,v)路径上割边去掉,即 --ans;v同理;
而向上跳的时候可以用并查集,把已经去掉的边,用路径压缩忽略掉,会往上跳的更快些。
memset记得写全,不然。。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define R register int
const int N=;
using namespace std;
inline int g() {
R ret=,fix=; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-:fix;
do ret=ret*+(ch^); while(isdigit(ch=getchar())); return ret*fix;
}
int n,m,cc,cnt,num,dcc,T;
int vr[N<<],nxt[N<<],fir[N],dfn[N],low[N],c[N],d[N],f[N][],fa[N];
bool bge[N<<];
inline void add(int u,int v) {vr[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;}
void tarjan(int u,int E) {
dfn[u]=low[u]=++num;
for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
if(!dfn[v]) {
tarjan(v,i);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u]) bge[i]=bge[i^]=true;
} else if(i!=(E^))low[u]=min(low[u],low[v]);
}
}
void dfs(int u) {
c[u]=dcc;
for(R i=fir[u];i;i=nxt[i]) if(!bge[i]&&!c[vr[i]]) dfs(vr[i]);
}
int ff[N],vv[N<<],nn[N<<],tc=;
inline void addc(int u,int v) {vv[++tc]=v,nn[tc]=ff[u],ff[u]=tc;}
inline void solve() {
for(R i=;i<=cnt;++i) {
R u=vr[i^],v=vr[i];
if(c[u]==c[v]) continue;
addc(c[u],c[v]);
}
}
void ldfs(int u) {
for(R i=ff[u];i;i=nn[i]) { R v=vv[i];
if(d[v]) continue;
f[v][]=u,d[v]=d[u]+; R p=u;
for(R j=;f[p][j];++j) f[v][j+]=f[p][j],p=f[p][j];
ldfs(v);
}
}
inline int lca(int u,int v) {
if(d[u]<d[v]) swap(u,v); R lim=log2(d[u])+;
for(R i=lim;i>=;--i) if(d[f[u][i]]>=d[v]) u=f[u][i];
if(u==v) return u;
for(R i=lim;i>=;--i) if(f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i];
return f[u][];
}
int getf(int x) {return x==fa[x]?x:fa[x]=getf(fa[x]);}
signed main() {
while(n=g(),m=g(),m||n) { cnt=;tc=;num=dcc=cc=;
memset(dfn,,sizeof(dfn));memset(low,,sizeof(low));memset(nxt,,sizeof(nxt));memset(fir,,sizeof(fir));
memset(bge,false,sizeof(bge));memset(nn,,sizeof(nn));memset(ff,,sizeof(ff)); memset(c,,sizeof(c));memset(f,,sizeof(f));
for(R i=,u,v;i<=m;++i) u=g(),v=g(),add(u,v),add(v,u);
for(R i=;i<=n;++i) if(!dfn[i]) tarjan(i,);
for(R i=;i<=n;++i) if(!c[i]) ++dcc,dfs(i);
for(R i=;i<=n;++i) fa[i]=i;
solve(); d[]=;ldfs(); R q=g(),ans=dcc-;
printf("Case %d:\n",++T);
while(q--) {
R u=g(),v=g();
u=c[u],v=c[v]; R L=lca(u,v); //cout<<L<<'\n';
u=getf(u),v=getf(v);
while(d[u]>d[L]) fa[u]=f[u][],--ans,u=getf(u);
while(d[v]>d[L]) fa[v]=f[v][],--ans,v=getf(v);
printf("%d\n",ans);
} putchar('\n');
}
74 }
2019.04.12
POJ3694 Network 边双缩点+LCA+并查集的更多相关文章
- POJ3694 Network —— 边双联通分量 + 缩点 + LCA + 并查集
题目链接:https://vjudge.net/problem/POJ-3694 A network administrator manages a large network. The networ ...
- poj3694 Network[边双缩点+树剖/并查集]
首先同一个点双内部的加边肯定不影响..所以先缩点成树,然后每次加一条边,这条对应的树上路径上所有边就都不是桥了,且每次操作独立作用,不相互影响(不过有可能本来一条边已经不是桥了又被标记了一次),所以每 ...
- POJ 3694Network(Tarjan边双联通分量 + 缩点 + LCA并查集维护)
[题意]: 有N个结点M条边的图,有Q次操作,每次操作在点x, y之间加一条边,加完E(x, y)后还有几个桥(割边),每次操作会累积,影响下一次操作. [思路]: 先用Tarjan求出一开始总的桥的 ...
- POJ 3694 (tarjan缩点+LCA+并查集)
好久没写过这么长的代码了,题解东哥讲了那么多,并查集优化还是很厉害的,赶快做做前几天碰到的相似的题. #include <iostream> #include <algorithm& ...
- Poj 3694 Network (连通图缩点+LCA+并查集)
题目链接: Poj 3694 Network 题目描述: 给出一个无向连通图,加入一系列边指定的后,问还剩下多少个桥? 解题思路: 先求出图的双连通分支,然后缩点重新建图,加入一个指定的边后,求出这条 ...
- Codevs 3287 货车运输 2013年NOIP全国联赛提高组(带权LCA+并查集+最大生成树)
3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description A 国有 n 座 ...
- 【CodeForces】827 D. Best Edge Weight 最小生成树+倍增LCA+并查集
[题目]D. Best Edge Weight [题意]给定n个点m条边的带边权无向连通图,对每条边求最大边权,满足其他边权不变的前提下图的任意最小生成树都经过它.n,m<=2*10^5,1&l ...
- POJ3694 Network(Tarjan双联通分图 LCA 桥)
链接:http://poj.org/problem?id=3694 题意:给定一个有向连通图,每次增加一条边,求剩下的桥的数量. 思路: 给定一个无向连通图,添加一条u->v的边,求此边对图剩余 ...
- ZOJ 4097 Rescue the Princess 边双缩点+LCA
给你一个图和三个点U,V,W 问你是否存在从U到V和从U到W的两条边不相交路径 先边双缩点 再每个连通分量搞LCA 最后LCA判 #include<bits/stdc++.h> usin ...
随机推荐
- ubuntn14.04 使用 nvm创建多版本node环境
1. 下载 nvm wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.32.1/install.sh | bash 2. 然后 ...
- centos6.3 安装python2.7.3
现在比较流行python2.7版本,centos6.3的默认版本是2.6.6,所以需要安装下2.7版本 1.下载安装python2.7 #wget http://www.python.org/ftp/ ...
- POJ 3620 Avoid The Lakes(dfs算法)
题意:给出一个农田的图,n行m列,再给出k个被淹没的坐标( i , j ).求出其中相连的被淹没的农田的最大范围. 思路:dfs算法 代码: #include<iostream> #inc ...
- OP趋势系统
经过3年多时间的摸索,经历过熊市牛市的历练,终于完成坚持已久的OP趋势系统的实践,接下来,我将在股灾后,每天都分享OP趋势系统的信号,可以很负责任的说,经过10年历史数据的测试,加上3年的实盘,更加坚 ...
- web前端js过滤敏感词
web前端js过滤敏感词 这里是用文本输入框还有文本域绑定了失去焦点事件,然后再遍历敏感词数组进行匹配和替换. var keywords=["阿扁","呵呵", ...
- 浅析linux 下shell命令执行和守护进程
执行shell脚本有以下几种方式 1.相对路径方式,需先cd到脚本路径下 [root@banking tmp]# cd /tmp [root@banking tmp]# ./ceshi.sh 脚本执行 ...
- HDU-6035:Colorful Tree(虚树+DP)
这里有三道长得像的题: 一:HDU6036: There is a tree with nn nodes, each of which has a type of color represented ...
- poj 2719 Faulty Odometer
Description You are given a car odometer which displays the miles traveled as an integer. The odomet ...
- MySQL学习_查看各仓库产品的销售情况_20161102
订单表结构是具体到每个订单下面多个产品,而仓库出货的表结构是对每个订单的金额汇总 不区分订单产品 因此如果想计算每个仓库每个产品的销售情况 需要将两个表连接起来 并且产品是昨天在线且有库存的产品 #昨 ...
- P2766 [网络流24题]最长不下降子序列问题
ha~ «问题描述: 给定正整数序列$x_1,...,x_n$ .$n<=500$ 求(1)计算其最长不下降子序列的长度$s$. (2)计算从给定的序列中最多可取出多少个长度为$s$的不下降子序 ...