题目链接

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

用\(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. Unity3d学习日记(三)

      使用Application.LoadLevel(Application.loadedLevel);来重新加载游戏scene的方法已经过时了,我们可以使用SceneManager.LoadScene ...

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

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

  3. java数据结构-HashMap

    一直以来似乎都有一个错觉,认为map跟其他的集合类一样继承自Collection,其实不然,Map和Collection在结构层次上是没有任何关系的,通过查看源码可以发现map所有操作都是基于key- ...

  4. [剑指Offer] 61.序列化二叉树

    题目描述 请实现两个函数,分别用来序列化和反序列化二叉树 /* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *r ...

  5. 使用户浏览器添加没有的字体@font-face

    @font-face的用法 @font-face { font-family: 'MyWebFont'; src: url('webfont.eot'); /* IE9 Compat Modes */ ...

  6. 单点登录Windows实现

    Windows实现步骤: server.xml修改方式 hosts修改方式 CAS客户端配置 CAS配置filter.txt内容如下: <!-- ======================== ...

  7. BZOJ 2208 连通数(强连通分量)

    先缩点,对于缩完点后的DAG,可以直接在每个scc dfs一次就可以求出终点是这个scc的点的点对个数. # include <cstdio> # include <cstring& ...

  8. BZOJ 1055 玩具取名(区间DP)

    很显然的区间DP,定义dp[i][j][k], 如果dp[i][j][k]=1表示字符串[i,j]可以组成k字符. # include <cstdio> # include <cst ...

  9. 【题解】Atcoder ARC#94 F-Normalization

    再次膜拜此强题!神级性质之不可能发现系列收藏++:首先,对于长度<=3的情况,我们采取爆搜答案(代码当中是打表).对于长度>=4的情况,则有如下几条玄妙的性质: 首先我们将 a, b, c ...

  10. 【题解】洛谷9月月赛加时赛 —— Never·island

    有趣有趣~ヾ(✿゚▽゚)ノ真的很有意思的一道dp题!感觉可以提供很多非常有意思的思路~ 现场打的时候考虑了很久,但并没有做出来,主要还是卡在了两个地方:1.考虑到按照端点来进行dp,但没有办法将两个端 ...