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\) 中的一种颜色 . 对于任意一个简 ...
随机推荐
- Webpack 4 Tree Shaking 终极优化指南
几个月前,我的任务是将我们组的 Vue.js 项目构建配置升级到 Webpack 4.我们的主要目标之一是利用 tree-shaking 的优势,即 Webpack 去掉了实际上并没有使用的代码来减少 ...
- 监听器以及在监听类里面获得bean的方法
1实现HttpSessionListener和ServletContextListener,2个接口 2然后在contextInitialized初始化方法里面: ServletContext app ...
- SqlServer2005 查询 第四讲 in
今天我们来说sql中的命令参数in in --in用于查询某个字段的指定的值的记录信息 注意一下:--对或(or)取反是并且(and),对并且(and)取反是或(or 数据库中不等于表示有两种:!= ...
- 设计模式(Java语言)- 简单工厂模式
简单工厂模式有称为静态工厂模式,属于设计模式中的创建型模式.简单工厂模式通过对外提供一个静态方法来统一为类创建实例.简单工厂模式的目的是实现类与类之间解耦,其次是客户端不需要知道这个对象是如何被穿创建 ...
- vue根据不同环境进行编译打包
工作中我们在开发过程中,有很多的开发环境,如果我们不进行统一配置,那么我们只能手动进行更改,这样会给我们带来诸多不便,所以我们要配置根据不同的环境来进行编译打包. 先看一下我的项目目录: 在confi ...
- nyoj 844-A+B Problem(V) (string[::-1] 字符串反转)
844-A+B Problem(V) 内存限制:64MB 时间限制:1000ms 特判: No 通过数:14 提交数:17 难度:1 题目描述: 做了A+B Problem之后,Yougth感觉太简单 ...
- MySQL数据库root账户密码忘记两种处理方法(保有效)
方法1: 1.停止MySQL服务 # kill `cat /var/run/mysqld/mysqld.pid` 或者 # pkill mysqld 2.创建一个密码赋值语句的文本文件 # vi my ...
- django 中 css文件的调用
Django: 配置css文件 晚上搞了好久的css文件的调用,发现,我根本文件位置都放错了. 接下来要更改settings.py 和 urls.py 的设定. Settings.py 中应该: ur ...
- mysql清空数据库下所有的表
一.使用以下命名获取truancate 数据库 lz_garden 下所有表,并将其导入到 d盘 为 out.sql select Concat('TRUNCATE TABLE ', TABLE_N ...
- selenium介绍和环境搭建
一.简单介绍 1.selenium:Selenium是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE.Mozilla Fire ...