HDU3896 Greatest TC(双联通分量+倍增)
Problem Description
The railways and the rail-stations in TC are fragile and always meet with different kinds of problems. In order to reach the destination safely on time, you are asked to develop a system which has two types of main functions as below.
1: A B C D, reporting whether we can get from station A to station B without passing the railway that connects station C and station D.
2: A B C, reporting whether we can get from station A to station B without passing station C.
Please notice that the railways are UNDIRECTED.
Input
The stations are always labeled from 1 to N.
Output
题解:
分成三种情况讨论:
1: a,b都在子树c中,如果a,b在c的同一个儿子当中,那么去掉c是联通的;否则让a,b往上跳,变成c的两个儿子,如果lown(a)>=dfn(c) 或 lown(b)>=dfn(c)成立,那么不连通;
2:a,b只又一个在子树c中,假设a在子树c中,那么,同样让a往上跳,变成c的儿子,.如果lown[a]>=dfn[c],那么不连通,否则联通;
3:a,b都不在子树c中,那么去掉c没有任何影响,所以还是联通(往上跳,可以用倍增法);
#include<bits/stdc++.h>
using namespace std;
#define mod 10007
#define pii pair<int,int>
#define pil pair<int,ll>
#define fi first
#define se second
#define mkp make_pair
#define PI acos(-1.0)
typedef long long ll;
const int INF=0x3f3f3f3f;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-') f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
}
inline ll readll()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-') f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
} const int maxn=1e5+;
const int maxm=5e5+; struct Edge{
int u,v;
int nxt;
} edge[maxm<<];
int n,m,head[maxn],tot,times;
int fa[maxn],dep[maxn],dfn[maxn],out[maxn],lown[maxn];
bool iscut[maxn],isbridge[maxn];
int anc[maxn][];
inline void AddEdge(int u,int v)
{
edge[tot].u=u;
edge[tot].v=v;
edge[tot].nxt=head[u];
head[u]=tot++;
} inline void Init()
{
tot=times=;
memset(head,-,sizeof(head));
memset(iscut,false,sizeof(iscut));
memset(isbridge,false,sizeof(isbridge));
memset(dep,,sizeof(dep));
memset(fa,,sizeof(fa));
} inline void dfs(int u)
{
dfn[u]=lown[u]=++times;
bool flag=false;
int child=;
for(int e=head[u];~e;e=edge[e].nxt)
{
int v=edge[e].v;
if(v==fa[u]) continue;
if(!dfn[v])
{
fa[v]=u;
dep[v]=dep[u]+;
dfs(v);
lown[u]=min(lown[u],lown[v]);
if(lown[v]>=dfn[u])
{
iscut[u]=true;
if(lown[v]>dfn[u]) isbridge[v]=true;
}
}
else lown[u]=min(lown[u],dfn[v]);
}
if(u== && child==) iscut[u]=false;
out[u]=times;
} inline bool subtree(int x,int y)
{
return (dfn[x]>=dfn[y]&&out[x]<=out[y])?:;
} inline void preprocess()
{
memset(anc,,sizeof(anc));
for(int i=;i<=n;++i) anc[i][]=fa[i];
for(int j=;(<<j)<n;++j)
for(int i=;i<=n;++i)
if(anc[i][j-]) anc[i][j]=anc[anc[i][j-]][j-];
} inline int upward(int u, int x)
{
for(int i=;i<;i++)
if((x>>i)&) u=anc[u][i];
return u;
} inline bool Judge(int a,int b,int c)
{
int in1=subtree(a,c);
int in2=subtree(b,c);
if(in1&in2)
{
a=upward(a,dep[a]-dep[c]-);
b=upward(b,dep[b]-dep[c]-);
if(a==b) return true;
if(lown[a]>=dfn[c]||lown[b]>=dfn[c]) return false;
}
if(in1^in2)
{
if(!in1) swap(a,b);
a=upward(a,dep[a]-dep[c]-);
if(lown[a]>=dfn[c]) return false;
}
return true;
} int main()
{
scanf("%d%d",&n,&m);
Init();
int u,v;
for(int i=;i<=m;++i)
{
u=read(),v=read();
AddEdge(u,v);AddEdge(v,u);
}
dfs();preprocess();
int q=read();
while(q--)
{
int typ,a,b,c,d;
typ=read();a=read();b=read();c=read();
if(typ==)
{
d=read();
if(dep[c]<dep[d]) swap(c,d);
int temp1=subtree(a,c);
int temp2=subtree(b,c);
if(isbridge[c]&&(temp1^temp2)) puts("no");
else puts("yes");
}
else
{
bool ok=Judge(a,b,c);
if(ok) puts("yes");else puts("no");
}
}
return ;
}
HDU3896 Greatest TC(双联通分量+倍增)的更多相关文章
- POJ 3694Network(Tarjan边双联通分量 + 缩点 + LCA并查集维护)
[题意]: 有N个结点M条边的图,有Q次操作,每次操作在点x, y之间加一条边,加完E(x, y)后还有几个桥(割边),每次操作会累积,影响下一次操作. [思路]: 先用Tarjan求出一开始总的桥的 ...
- 『Tarjan算法 无向图的双联通分量』
无向图的双连通分量 定义:若一张无向连通图不存在割点,则称它为"点双连通图".若一张无向连通图不存在割边,则称它为"边双连通图". 无向图图的极大点双连通子图被 ...
- 【UVA10972】RevolC FaeLoN (求边双联通分量)
题意: 给你一个无向图,要求把所有无向边改成有向边,并且添加最少的有向边,使得新的有向图强联通. 分析: 这题的解法还是很好想的.先用边双联通分量缩点,然后找新图中入度为0和为1的点,入度为0则ans ...
- lightoj 1300 边双联通分量+交叉染色求奇圈
题目链接:http://lightoj.com/volume_showproblem.php?problem=1300 边双连通分量首先dfs找出桥并标记,然后dfs交叉着色找奇圈上的点.这题只要求在 ...
- HDU5409---CRB and Graph 2015多校 双联通分量缩点
题意:一个联通的无向图, 对于每一条边, 若删除该边后存在两点不可达,则输出这两个点, 如果存在多个则输出第一个点尽可能大,第二个点尽可能小的. 不存在输出0 0 首先 若删除某一条边后存在多个联通分 ...
- poj2942(双联通分量,交叉染色判二分图)
题意:一些骑士,他们有些人之间有矛盾,现在要求选出一些骑士围成一圈,圈要满足如下条件:1.人数大于1.2.总人数为奇数.3.有仇恨的骑士不能挨着坐.问有几个骑士不能和任何人形成任何的圆圈. 思路:首先 ...
- 大白书中无向图的点双联通分量(BCC)模板的分析与理解
对于一个无向图,如果任意两点至少存在两条点不重复(除起点和终点外无公共点)的路径,则这个图就是点双联通. 这个要求等价于任意两条边都存在于一个简单环(即同一个点不能在圈中出现两次)中,即内部无割点. ...
- 洛谷P2860 [USACO06JAN]冗余路径Redundant Paths(tarjan求边双联通分量)
题目描述 In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numbered 1. ...
- ARC062 - F. Painting Graphs with AtCoDeer (Polya+点双联通分量)
似乎好久都没写博客了....赶快来补一篇 题意 给你一个 \(n\) 个点 , 没有重边和自环的图 . 有 \(m\) 条边 , 每条边可以染 \(1 \to k\) 中的一种颜色 . 对于任意一个简 ...
随机推荐
- 两张图弄懂函数的递归(以golang为例)
函数递归时要遵守的原则: 执行一个函数时,就要创建一个新的受保护的独立空间(新函数栈) 函数的局部变量是独立的,不会相互影响: 递归必须向退出递归的条件逼近,否则就会无限递归: 当一个函数执行完毕,或 ...
- Python 基础 三 反射
Python 基础 三 反射 今天我们先介绍一下反射这个概念,啥是反射?反射就是自己检测自己.在我们Python的面向对象中的反射是啥意思呢?就是通过字符串的形式操作对象相关的属性.python中的一 ...
- 使用Bootstrap制作简单的旅游主页
页面效果 代码: 需要导入bootstrapt文件,解压至项目中. 下载地址:https://v3.bootcss.com/getting-started/#download <!DOCTYPE ...
- vue 前端处理监听关键字搜索
根据组件的业务需要,有时候搜索是把关键字返回给后台,后台处理后再把数据返回给前端渲染(多次请求服务器):有时候是前端把页面的数据全部获取下来,前端处理关键字的搜索(影响页面加载) 我这个文章是介绍第二 ...
- 删除TFS上的团队项目
Visual Studio 提供了一个工具 在X:\X\Microsoft Visual Studio X\Common7\IDE Visual Studio安装路径 下 TFSDeletepr ...
- lqb 入门训练 Fibonacci数列 (循环 PS:提柜要栈溢出)
入门训练 Fibonacci数列 时间限制:1.0s 内存限制:256.0MB 问题描述 Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1. 当n比较大时, ...
- ubuntu18 拨号连接宽带网络方法
1.打开终端查看以太网网卡编号 2.打开/usr/share/applications/ 3.点击network connections 4.点击左下角的+号 5.连接类型选择DSL/PPPoE 6. ...
- 06_K-近邻算法
k-近邻算法 算法介绍 定义: 如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一类别,则该样本也属于这个类别. 计算距离公式:欧式距离 (两点之间距离) 需要做标准化 ...
- 建筑行业的新起之秀---BIM
近年来,BIM在国家在建筑行业的推进下逐渐走近人们的视线,而且BIM技术是作为建筑领域的一项新技术行业发展的越来越好,在很多的建筑场景都用到了BIM建模.施工.运维以及BIM+GIS等以BIM为 ...
- Springboot 系列(十六)你真的了解 Swagger 文档吗?
前言 目前来说,在 Java 领域使用 Springboot 构建微服务是比较流行的,在构建微服务时,我们大多数会选择暴漏一个 REST API 以供调用.又或者公司采用前后端分离的开发模式,让前端和 ...