原题链接:P2783 有机化学之神偶尔会做作弊

一看,是黑题,太毒瘤了,不写

什么单链??!

只会画有机化学中正六边形的我觉得这样不行QAQ(我才初二)

当然,题目也给你了详细的解释

实际呢,这道题先给你了一个图,让你把图中的环全缩成一个点,在求两个点之间的距离

这道题估计是你谷最简单黑题

先用tarjan缩点,再重新建图

在新建的图上跑lca求距离

就是这么简单

代码上有些细节需要注意

#pragma GCC optimize("O3")
#define N 100001
#include <bits/stdc++.h>
using namespace std;
inline int read()
{
register int f=1,x=0;
register char ch;
do{
ch=getchar();
if(ch=='-')
f=-1;
}while(ch<'0'||ch>'9');
do{
x=x*10+ch-'0';
ch=getchar();
}while(ch>='0'&&ch<='9');
return f*x;
}
inline int Min(register int a,register int b)
{
if(a<b)
return a;
return b;
}
inline void Swap(register int &a,register int &b)
{
a^=b^=a^=b;
}
int tmp[64];
inline void print(register int res)
{
if(res==0)
{
puts("0");
return;
}
if(res<0)
{
putchar('-');
res=0-res;
}
while(res)
tmp[++tmp[0]]=res&1,res>>=1;
while(*tmp)
putchar(tmp[(*tmp)--]+'0');
putchar('\n');
}
int n,m,tot,q,sign,top,cnt;
int first[N<<1][2],next[N<<1][2],to[N<<1][2],dfn[N],low[N],sta[N],id[N],dep[N];
int p[N][50],xx[N],yy[N];
bool insta[N];
inline void ADD(register int x,register int y,register int w)
{
next[++tot][w]=first[x][w];
to[tot][w]=y;
first[x][w]=tot;
}
inline void add(register int x,register int y,register int w)
{
ADD(x,y,w);
ADD(y,x,w);
}
inline void DFS(register int x,register int fa)
{
dfn[x]=low[x]=++sign;
sta[++top]=x;
insta[x]=true;
int k=first[x][0],u;
while(k)
{
u=to[k][0];
if(u==fa)
{
k=next[k][0];
continue;
}
if(!dfn[u])
{
DFS(u,x);
low[x]=Min(low[u],low[x]);
}
else if(insta[u])
low[x]=Min(low[x],dfn[u]);
k=next[k][0];
}
if(low[x]==dfn[x])
{
++cnt;
while(19260817)
{
int y=sta[top--];
id[y]=cnt;
if(x==y)
break;
}
}
return;
}
inline void rebuild()
{
tot=0;
for(register int i=1;i<=m;++i)
if(id[xx[i]]!=id[yy[i]])
add(id[xx[i]],id[yy[i]],1);
}
inline void DFS2(register int son,register int fa)
{
dep[son]=dep[fa]+1;
p[son][0]=fa;
for(register int i=first[son][1];i;i=next[i][1])
if(to[i][1]!=fa)
DFS2(to[i][1],son);
}
inline int LCA(register int a,register int b)
{
if(a==b)
return a;
if(dep[a]>dep[b])
Swap(a,b);
for(register int i=20;i>=0;--i)
if(dep[p[b][i]]>=dep[a])
b=p[b][i];
if(a==b)
return a;
for(register int i=20;i>=0;--i)
if(p[a][i]!=p[b][i])
a=p[a][i],b=p[b][i];
return p[a][0];
}
int main()
{
n=read(),m=read();
for(register int i=1;i<=m;++i)
{
xx[i]=read(),yy[i]=read();
add(xx[i],yy[i],0);
}
for(register int i=1;i<=n;++i)
if(!dfn[i])
DFS(i,0);
rebuild();
DFS2(1,0);
for(register int i=1;i<=20;++i)
for(register int j=1;j<=cnt;++j)
p[j][i]=p[p[j][i-1]][i-1];
q=read();
while(q--)
{
int a=read(),b=read();
a=id[a],b=id[b];
int lca=LCA(a,b),ans=0;
ans=dep[a]+dep[b]-(dep[lca]<<1)+1;
print(ans);
}
return 0;
}

【题解】Luogu P2783 有机化学之神偶尔会做作弊的更多相关文章

  1. luogu P2783 有机化学之神偶尔会做作弊 |Tarjan+LCA

    题目背景 XS中学化学竞赛组教练是一个酷爱炉石的人. 有一天他一边搓炉石一边监考,而你作为一个信息竞赛的大神也来凑热闹. 然而你的化竞基友却向你求助了. "第1354题怎么做"&l ...

  2. LuoGu P2783 有机化学之神偶尔会做作弊

    题目传送门 人生第一道黑题呢,虽然这题是黑题中的水题并且我调了一整节课,但是我还是很兴奋啊.毕竟人生第一道黑题啊 这个题根据题意,先把整个图进行tarjan缩点,建出一棵树,对于每一组询问,两点之间的 ...

  3. 洛谷 P2783 有机化学之神偶尔会做作弊 解题报告

    P2783 有机化学之神偶尔会做作弊 题目背景 XS中学化学竞赛组教练是一个酷爱炉石的人. 有一天他一边搓炉石一边监考,而你作为一个信息竞赛的大神也来凑热闹. 然而你的化竞基友却向你求助了. &quo ...

  4. [洛谷P2783]有机化学之神偶尔会做作弊

    第一次做出来黑题祭 虽然感觉难度其实并不到黑题的难度 题解: 其实这道题并没用什么特别的知识,只是Tarjan求双联通分量和LCA的结合. 所以,我们可以很显然的发现(如此恶劣的词汇,逃 这道题其实就 ...

  5. 洛谷 P2783 有机化学之神偶尔会做作弊(Tarjan,LCA)

    题目背景 LS中学化学竞赛组教练是一个酷爱炉石的人. 有一天他一边搓炉石一边监考,而你作为一个信息竞赛的大神也来凑热闹. 然而你的化竞基友却向你求助了. “第1354题怎么做”<--手语 他问道 ...

  6. Tarjan+LCA【洛谷P2783】 有机化学之神偶尔会做作弊

    [洛谷P2783] 有机化学之神偶尔会做作弊 题目背景 XS中学化学竞赛组教练是一个酷爱炉石的人. 有一天他一边搓炉石一边监考,而你作为一个信息竞赛的大神也来凑热闹. 然而你的化竞基友却向你求助了. ...

  7. P2783 有机化学之神偶尔也会作弊 题解

    题面 前言 这道题以前还是道(水)黑题,现在怎么降紫了???? 前置芝士 tarjain 缩点 倍增求LCA或树剖求LCA 脑子... 题意 给你一个无向图,要求你把所有的环缩成一个点.在新得到的图上 ...

  8. 【洛谷 P2783】 有机化学之神偶尔会做作弊 (双联通分量)

    题目链接 可能是除了<概率论>的最水的黑题了吧 用\(Tarjan\)缩点(点双联通分量),然后就是树上两点之间的距离了,跑\(LCA\)就好了. #include <cstdio& ...

  9. Tarjan缩点+LCA【p2783】有机化学之神偶尔会做作弊

    Description 你翻到那一题:给定一个烃,只含有单键(给初中生的一个理解性解释:就是一堆碳用横线连起来,横线都是单条的). 然后炎魔之王拉格纳罗斯用他的火焰净化了一切环(???).所有的环状碳 ...

随机推荐

  1. 动手动脑(&课后实验):类和对象

    1. 以下代码为何无法通过编译?哪儿出错了? 如果类提供了一个自定义的构造方法,将导致系统不再提供默认构造方法.而此时程序中已提供了一个有一个参数的构造函数,而定义对象时却没有参数,所以程序会报错. ...

  2. vue+element-ui中的表单验证(电话等等)

    1. 2. 3. ============================================================上代码============================ ...

  3. Selenium基础知识(二)鼠标操作

    一.鼠标操作 这个需要使用webdriver下的ActionChains类,这个类是操作鼠标操作的: from selenium.webdriver import ActionChains 鼠标操作可 ...

  4. Oracle 11g快速收集全库统计信息

    环境:Oracle 11.2.0.4 采用并行的方式,快速收集全库统计信息,多用于跨版本升级之后,对全库的统计信息重新进行快速收集: --开启计时 set timing on --设置并行收集 exe ...

  5. linux df查看硬盘使用量 du查看文件所占大小

    df 常用来查看磁盘的占用情况. du 常用来查看文件夹的大小等. Linux命令: df  [-ahikHTm]  [目录或者文件夹] 参数: -h : 以交较易识别的方式展示使用量  111100 ...

  6. WebSocket.之.基础入门-前端发送消息

    WebSocket.之.基础入门-前端发送消息 在<WebSocket.之.基础入门-建立连接>的代码基础之上,进行添加代码.代码只改动了:TestSocket.java 和 index. ...

  7. LeetCode112.路径总和

    给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和. 说明: 叶子节点是指没有子节点的节点. 示例: 给定如下二叉树,以及目标和 sum = 22 ...

  8. 20155228 2016-2017-2 《Java程序设计》第2周学习总结

    20155228 2006-2007-2 <Java程序设计>第2周学习总结 教材学习内容总结 类型 Java可以区分为基本类型和类类型(或称参考类型).对于基本类型,使用时得考虑一下数据 ...

  9. [openjudge-搜索]深度优先搜索之马走日

    题目描述 描述 马在中国象棋以日字形规则移动.请编写一段程序,给定n*m大小的棋盘,以及马的初始位置(x,y),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点. 输入 第一行 ...

  10. Java8函数式编程探秘

    引子 将行为作为数据传递 怎样在一行代码里同时计算一个列表的和.最大值.最小值.平均值.元素个数.奇偶分组.指数.排序呢? 答案是思维反转!将行为作为数据传递. 文艺青年的代码如下所示: public ...