题目链接

可能是除了《概率论》的最水的黑题了吧

用\(Tarjan\)缩点(点双联通分量),然后就是树上两点之间的距离了,跑\(LCA\)就好了。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int s; char ch;
inline int read(){
s = 0; ch = getchar();
while(ch < '0' || ch > '9') ch = getchar();
while(ch >= '0' && ch <= '9') { s = s * 10 + ch - '0'; ch = getchar(); }
return s;
}
const int MAXN = 10010;
const int MAXM = 50010;
int dfn[MAXN], low[MAXN], id, bridge[MAXM << 1], dcc, belong[MAXN], top, vis[MAXN];
int n, m, a, b, head[MAXN], num = 1, f[MAXN][20], dep[MAXN], t, stack[MAXN];
struct Edge{
int from, next, to;
}e[MAXM << 2];
inline void Add(int from, int to){
e[++num].to = to; e[num].from = from; e[num].next = head[from]; head[from] = num;
e[++num].to = from; e[num].from = to; e[num].next = head[to]; head[to] = num;
}
void Tarjan(int u, int fa){
dfn[u] = low[u] = ++id; stack[++top] = u; vis[u] = 1;
for(int i = head[u]; i; i = e[i].next)
if(e[i].to != fa)
if(!dfn[e[i].to]){
Tarjan(e[i].to, u);
low[u] = min(low[u], low[e[i].to]);
}
else if(vis[e[i].to])
low[u] = min(low[u], dfn[e[i].to]);
if(dfn[u] == low[u]){
++dcc;
do
belong[stack[top]] = dcc;
while(stack[top--] != u);
}
}
void getDF(int u, int fa){
f[u][0] = fa; dep[u] = dep[fa] + 1;
for(int i = head[u]; i; i = e[i].next)
if(e[i].to != fa)
getDF(e[i].to, u);
}
int LCA(int u, int v){
if(dep[u] < dep[v]) swap(u, v);
int cha = dep[u] - dep[v];
if(cha)
for(int i = 0; i <= 18; ++i)
if((cha >> i) & 1)
u = f[u][i];
if(u != v){
for(int i = 18; ~i; --i)
if(f[u][i] != f[v][i])
u = f[u][i], v = f[v][i];
return f[u][0];
}
return u;
}
int dis(int u, int v){
return dep[u] + dep[v] - (dep[LCA(u, v)] << 1) + 1;
}
void print(int x){
if(x > 1) print(x >> 1);
printf("%d", x & 1);
}
int main(){
n = read(); m = read();
for(int i = 1; i <= m; ++i)
Add(read(), read());
for(int i = 1; i <= n; ++i)
if(!dfn[i])
Tarjan(i, 0);
memset(head, 0, sizeof head);
int tmp = num;
for(int i = 2; i <= tmp; i += 2)
if(belong[e[i].from] != belong[e[i].to])
Add(belong[e[i].from], belong[e[i].to]);
getDF(1, 0);
for(int j = 1; j <= 18; ++j)
for(int i = 1; i <= dcc; ++i)
f[i][j] = f[f[i][j - 1]][j - 1];
t = read();
while(t--) print(dis(belong[read()], belong[read()])), puts("");
return 0;
}

【洛谷 P2783】 有机化学之神偶尔会做作弊 (双联通分量)的更多相关文章

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

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

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

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

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

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

  4. 【题解】Luogu P2783 有机化学之神偶尔会做作弊

    原题链接:P2783 有机化学之神偶尔会做作弊 一看,是黑题,太毒瘤了,不写 什么单链??! 只会画有机化学中正六边形的我觉得这样不行QAQ(我才初二) 当然,题目也给你了详细的解释 实际呢,这道题先 ...

  5. 洛谷P2783 有机化学之神偶尔会作弊

    题目传送门 啦啦啦,发个文纪念一下第一道在洛谷上A的黑题,一次性就过真是无比舒服-(虽然某些大佬说这题有点水……)题目其实思路不难,Tarjan缩点+LCA,不过因为是无向边,所以在Tarjan的时候 ...

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

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

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

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

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

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

  9. [luogu2783] 有机化学之神偶尔会做作弊

    题目链接 洛谷. Solution 边双缩点然后\(lca\)跑\(dis\)就好了. 注意这里是边双,不知道为啥所有题解都说的是点双. 边双是定义在点上的,即每个点只属于一个边双:点双是定义在边上的 ...

随机推荐

  1. Swift-函数的理解

    /* 函数(Function) 函数是为执行特定功能的自包含的代码块.函数需要给定一个特定标识符(名字),然后当需要的时候, 就调用此函数来执行功能. */ // 函数的定义与调用 // 定义函数时, ...

  2. PokeCats开发者日志(十四)——终章

      已经不知道离PokeCats游戏开始开发有多少个晚上了,今晚心血来潮整理随笔的时候发现这个故事还没有划上句号.   故事的结局是最终我拿到了软著权,但是没办法上架到任何一个知名的安卓app市场,连 ...

  3. 【Linux】- netstat 命令

    Linux netstat命令用于显示网络状态.利用netstat指令可让你得知整个Linux系统的网络情况. 语法 netstat [-acCeFghilMnNoprstuvVwx][-A<网 ...

  4. parse_str — 将字符串解析成多个变量

    $arr2="first=value1&second=value2&third[]=value3&third[]=value4"; parse_str($a ...

  5. Swoole和Swoft的那些事 (Http/Rpc服务篇)

    https://www.jianshu.com/p/4c0f625d5e11 Swoft在PHPer圈中是一个门槛较高的Web框架,不仅仅由于框架本身带来了很多新概念和前沿的设计,还在于Swoft是一 ...

  6. WPF对某控件添加右键属性

    代码创建右键属性 ContextMenu cm = new ContextMenu(); MenuItem mi = new MenuItem(); mi.Header = "打开此文件所有 ...

  7. set类型没有单独取值功能 通过循环取值

    set类型没有单独取值功能 通过循环取值

  8. BZOJ 1797 最小割(最小割割边唯一性判定)

    问题一:是否存在一个最小代价路径切断方案,其中该道路被切断? 问题二:是否对任何一个最小代价路径切断方案,都有该道路被切断? 现在请你回答这两个问题. 最小割唯一性判定 jcvb: 在残余网络上跑ta ...

  9. prototype的本质

    在<关于思维方式的思绪>那篇文章里提到了, 原型的本质就是一种委托关系. 即我这里没有,就到我的原型里去看看,一旦找到就当成我的用. 本文详细说一下这个事情. 比如某女买东西,钱都是她老公 ...

  10. pascal语言中学版整理

    P1:主菜单File中的Command shell选项,可以暂时退出Pascal,进入DOS提示符状态,但Pascal仍然驻留在内存中.输入命令exit即可返回Pascal. P3:Edit菜单中Un ...