辣鸡错误:把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+并查集的更多相关文章

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

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

  2. poj3694 Network[边双缩点+树剖/并查集]

    首先同一个点双内部的加边肯定不影响..所以先缩点成树,然后每次加一条边,这条对应的树上路径上所有边就都不是桥了,且每次操作独立作用,不相互影响(不过有可能本来一条边已经不是桥了又被标记了一次),所以每 ...

  3. POJ 3694Network(Tarjan边双联通分量 + 缩点 + LCA并查集维护)

    [题意]: 有N个结点M条边的图,有Q次操作,每次操作在点x, y之间加一条边,加完E(x, y)后还有几个桥(割边),每次操作会累积,影响下一次操作. [思路]: 先用Tarjan求出一开始总的桥的 ...

  4. POJ 3694 (tarjan缩点+LCA+并查集)

    好久没写过这么长的代码了,题解东哥讲了那么多,并查集优化还是很厉害的,赶快做做前几天碰到的相似的题. #include <iostream> #include <algorithm& ...

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

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

  6. Codevs 3287 货车运输 2013年NOIP全国联赛提高组(带权LCA+并查集+最大生成树)

    3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description A 国有 n 座 ...

  7. 【CodeForces】827 D. Best Edge Weight 最小生成树+倍增LCA+并查集

    [题目]D. Best Edge Weight [题意]给定n个点m条边的带边权无向连通图,对每条边求最大边权,满足其他边权不变的前提下图的任意最小生成树都经过它.n,m<=2*10^5,1&l ...

  8. POJ3694 Network(Tarjan双联通分图 LCA 桥)

    链接:http://poj.org/problem?id=3694 题意:给定一个有向连通图,每次增加一条边,求剩下的桥的数量. 思路: 给定一个无向连通图,添加一条u->v的边,求此边对图剩余 ...

  9. ZOJ 4097 Rescue the Princess 边双缩点+LCA

    给你一个图和三个点U,V,W  问你是否存在从U到V和从U到W的两条边不相交路径 先边双缩点 再每个连通分量搞LCA 最后LCA判 #include<bits/stdc++.h> usin ...

随机推荐

  1. matlab之find()函数

    Find 这个函数用处也挺大的,这几天看很多程序都见到这一函数,今天要好好给阐述,了解下这个函数是为了找到矩阵或者是数组,向量中的非零元素.下面一大段英文没耐心看.看看例子就行了. 第一个用法是 nd ...

  2. IOS AppStore介绍图的尺寸大小(还有一些自己被拒的分享...)

    4s:640*960 5:640*1136 6:750*1334 6P:1242*2208 -------现在新版本的iTunes connect里只上传6P版本的大小就可以了,其他版本苹果会自动分辨 ...

  3. Codeforces 872C Maximum splitting:数学【分解成合数之和】

    题目链接:http://codeforces.com/contest/872/problem/C 题意: 给你一个数n,问你最多能将n分解成多少个合数之和.(若不能分解,输出-1) 题解: 若要让合数 ...

  4. Java企业微信开发_12_异常:java.lang.OutOfMemoryError: Java heap space

    一.异常现象 今天客户迁到正式环境,在做企业微信 接收消息服务器配置  时,出现如下异常: java.lang.OutOfMemoryError: Java heap space 二.异常原因 JAV ...

  5. 学习 Shell —— 括号、引号

    shell中各种括号的作用().(()).[].[[]].{} shell中的括号(小括号,大括号/花括号) ${},大括号用于确定变量的范围: $(( 数学运算 )) 0. 引号 单引号.双引号.飘 ...

  6. GIT的Push和Pull,强制Pull覆盖本地命令

    连接命令: git remote add origin + 你Git库的地址 其中,origin是你对这个Git库地址的标识. 一. 把文件从本地上传到库中 第一步:使用命令 git add命令把文件 ...

  7. BZOJ_2813_奇妙的Fibonacci_线性筛

    BZOJ_2813_奇妙的Fibonacci_线性筛 Description Fibonacci数列是这样一个数列: F1 = 1, F2 = 1, F3 = 2 . . . Fi = Fi-1 + ...

  8. chronoy & NTP

    同步时间 配置文件中/etc/chrony.conf 里面指定: server master iburst keyfile /etc/chrony.keys commandkey 1 allow al ...

  9. win7 64位搭建Mantis 缺陷管理系统

    什么是Mantis MantisBT is a free popular web-based bugtracking system (feature list). It is written in t ...

  10. bzoj4176

    莫比乌斯反演 根据约数和个数公式 $ans = \sum_{i=1}^{n}\sum_{j=1}^{n}\sum_{x|i}\sum_{y|j}{[gcd(i, j)==1]}$ 交换枚举顺序 $an ...