整理的算法模板合集: ACM模板



我们知道在同一个边双连通分量中的点没有必经边(因为至少有两条分离的路径)。

所以我们直接tarjan求出桥后缩点,然后求一下树上两点间的距离即可。

那么如何求树上两点间距离呢,当然是用lca+bfs处理啦,答案就是dep[u]+dep[v]-2*dep[LCA(u,v)];

等等,

当然是树链剖分乱搞啦!

树链剖分乱搞:

正解lca:

啊这,树链剖分天下第一!(其实用树链剖分还TLE了一发,又交了一次运气好过了…)

其实主要是树链剖分给我们提供了一种暴力的思路,让我们不用分析想正解就能有机会AC,比较适合我这种没脑子的人hhh

树链剖分AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 2000007, M = 5000007, INF = 0x3f3f3f3f;int n, m;
int head[N], ver[M], nex[M], tot;
int hc[N], vc[M], nc[M], tc;
int dcc[N], dcc_cnt;
int bridge[N], dfn[N], low[N], num;
int root = 1;void add(int x, int y)
{ver[tot] = y;nex[tot] = head[x];head[x] = tot ++ ;
}void add_c(int x, int y)
{vc[tc] = y;nc[tc] = hc[x];hc[x] = tc ++ ;
}void tarjan(int x, int in_edge = 0)
{dfn[x] = low[x] = ++ num;for(int i = head[x]; ~i; i = nex[i]){if(i == (in_edge ^ 1))continue;int y = ver[i];if(!dfn[y]){tarjan(y, i);low[x] = min(low[x], low[y]);if(dfn[x] < low[y]){bridge[i] = bridge[i ^ 1] = true;}}else low[x] = min(low[x], dfn[y]);}
}void dfs(int x, int in_edge = 0)
{dcc[x] = dcc_cnt;for(int i = head[x]; ~i; i = nex[i]){int y = ver[i];if(i == (in_edge ^ 1) || bridge[i])continue;if(dcc[y] == 0)dfs(y, i);}
}int a[N], a_after[N];
struct Tree{int l, r;int lz;int sum;
}tr[N * 4];
int son[N];//重儿子
int id[N], fa[N], cnt, deep[N], sizes[N];
int top[N]; //重链顶点
int res = 0;inline void pushup(int p)
{tr[p].sum = tr[p << 1].sum + tr[p << 1 | 1].sum;
}inline void pushdown(int p)
{auto &root = tr[p], &left = tr[p << 1], &right = tr[p << 1 | 1];if(!root.lz)return ;left.lz += root.lz;right.lz += root.lz;left.sum = left.sum + root.lz * (left.r - left.l + 1);right.sum = right.sum + root.lz * (right.r - right.l + 1);root.lz = 0;
}void build(int p, int l, int r)
{tr[p] = {l, r, 0, 0};if(l == r){tr[p].sum = 0;return ;}int mid = l + r >> 1;build(p << 1, l, mid);build(p << 1 | 1, mid + 1, r);pushup(p);
}int query(int p, int l, int r)
{if(tr[p].l >= l && tr[p].r <= r){return tr[p].sum;}pushdown(p);int mid = tr[p].l + tr[p].r >> 1;int res = 0;if(l <= mid)res = (res + query(p << 1, l, r));if(r > mid)res = (res + query(p << 1 | 1, l, r));return res;
}void modify(int p, int l, int r, int k)
{if(tr[p].l >= l && tr[p].r <= r){tr[p].lz += k;tr[p].sum += k * (tr[p].r - tr[p].l + 1);return ;}int mid = tr[p].l + tr[p].r >> 1;pushdown(p);if(l <= mid)modify(p << 1, l, r, k);if(r > mid)modify(p << 1 | 1, l, r, k);pushup(p);return ;
}//-----------------------线段树
//找重儿子,记录深度
void dfs_son(int x, int father, int deeps)
{deep[x] = deeps;fa[x] = father;sizes[x] = 1;int max_son = -1;for(int i = hc[x]; ~i; i = nc[i]){int y = vc[i];if(y == father)continue;dfs_son(y, x, deeps + 1);sizes[x] += sizes[y];if(sizes[y] > max_son)son[x] = y,max_son = sizes[y];}
}//链接重链
void dfs_build(int x, int topfa)
{id[x] = ++ cnt;a_after[cnt] = a[x];top[x] = topfa;if(!son[x])return ;dfs_build(son[x], topfa);for(int i = hc[x]; ~i; i = nc[i]){int y = vc[i];if(y == fa[x] || y == son[x])continue;dfs_build(y, y);}
}int query_range(int x, int y)
{int res = 0;//类似并查集while(top[x] != top[y]){if(deep[top[x]] < deep[top[y]])swap(x, y);res = (res + query(1, id[top[x]], id[x]));x = fa[top[x]];//往上跳}if(deep[x] > deep[y])swap(x, y);res = res + query(1, id[x], id[y]);return res;
}void update_range(int x, int y, int z)
{while(top[x] != top[y]){if(deep[top[x]] < deep[top[y]])swap(x, y);modify(1, id[top[x]], id[x], z);x = fa[top[x]];}if(deep[x] > deep[y])swap(x, y);modify(1, id[x], id[y], z);
}int get_dist(int x, int y)
{update_range(x, y, 1);int res = query_range(x, y) - 1;update_range(x, y, -1);return res;
}int main()
{memset(head, -1, sizeof head);memset(hc, -1, sizeof hc);scanf("%d%d", &n, &m);for(int i = 1; i <= m; ++ i){int x, y;scanf("%d%d", &x, &y);add(x, y), add(y, x);}tarjan(1);//cout << "ok" << endl;for(int i = 1; i <= n ;++ i){if(dcc[i] == 0)++ dcc_cnt, dfs(i);}//cout << "ok" << endl;for(int x = 1; x <= n; ++ x){for(int i = head[x]; ~i;i = nex[i]){int y = ver[i];if(dcc[x] != dcc[y])add_c(dcc[x], dcc[y]);//add_c(dcc[y], dcc[x]);}}dfs_son(root, 0, 1);//cout << "ok1" << endl;dfs_build(root, root);//cout << "ok2" << endl;build(1, 1, n);//cout << "ok3" << endl;int q;scanf("%d", &q);while(q -- ){int x, y;scanf("%d%d", &x, &y);printf("%d\n", get_dist(dcc[x], dcc[y]));}return 0;
}

AcWing 397. 逃不掉的路(边双连通分量缩点成树 + 树链剖分乱搞)相关推荐

  1. 为什么劝你别去创业?大抵逃不掉这 101 个问题

    2016年底,当我的同事小白建议把我的思考整理成书的时候,大家都是沉默的.也许大家觉得创业这个话题成书是有难度的. 所以在这里我要感谢蓝狮子和浙江大学出版社,他们给了我这个机会.而在整理和思考的过程中 ...

  2. 哥几个又来看啦,进来吧逃不掉的(Linux精中之精)

    前言:天天敲代码主播的头都要炸了,估计拐友们也炸的一批,但咩办法学这个逃不掉的,乖乖敲吧,但为了让拐友们不是那么的痛苦,主播通宵给你们整理了Liunx精中之精的代码,保证外星人来了都能看懂.(ps:记 ...

  3. 逃不掉的小球-第10届蓝桥杯Scratch国赛真题第1题

    [导读]:超平老师计划推出Scratch蓝桥杯真题解析100讲,这是超平老师解读Scratch蓝桥真题系列的第22讲. 第10届蓝桥杯青少年组国赛于2019年5月25日举行,形式为线下考试,考生自带电 ...

  4. 逃不掉的是回忆,忘不了的是曾经:伤感日志

    逃不掉的是回忆,忘不了的是曾经:伤感日志 - 逃不掉的是回忆,忘不了的是曾经:伤感日志 [我以为我会是唯一的唯一] 开始,Start. 或许是我太天真的,曾经认为我是唯一的唯一. 可是现实一次次把我打 ...

  5. 几度苍凉的伤感独特日志发布:想要逃,却怎么也逃不掉

    几度苍凉的伤感独特日志发布:想要逃,却怎么也逃不掉 - 几度苍凉的伤感独特日志发布:想要逃,却怎么也逃不掉 当你问我:你会和我结婚吗?我不知道.当你问我:你会来看我吗?我不知道. 当你问我:四年后我们 ...

  6. P4320-道路相遇,P5058-[ZJOI2004]嗅探器【圆方树,LCA】

    两题差不多就一起写了 P4320-道路相遇 题目链接:https://www.luogu.com.cn/problem/P4320 题目大意 nnn个点mmm条边的一张图,qqq次询问两个点之间路径的 ...

  7. 双路cpu比单路强多少_电源单路好还是双路好?电脑电源单路和双路12V详细区别对比...

    在一些比较大功率的电源中,经常可以看到分为单路12V和双路甚至是多路12V两种规格.那么,电源单路好还是双路好呢,很多网友搞不清这个问题.下面"脚本之家"以最通俗易懂的描述,带大家 ...

  8. (揭秘监控技术)《潜行追踪》:FBI 给你28天,你也逃不掉,中国版呢?

    上周末,雷锋网编辑小李经人推荐,把美版<Hunted:潜行追踪>第一季刷完了. 这部剧为什么这么好看?和网络安全又有什么联系?要想知道这些问题的答案,先来简单介绍一下: <潜行追踪& ...

  9. 逃不掉的职场中年危机?

    [从发生在你我身边的裁员潮说起] 前段时间有位互联网公司的人力朋友M给我转了张图片,我一看还挺逗: 总之,人脉少的开滴滴,人脉多的做微商. 我给她发了个哭笑不得的表情包,她却有些严肃地回我: &quo ...

最新文章

  1. java.lang.ClassNotFoundException: com.mysql.jdbc.Driver 解决方法 java.lang.ClassNotFoundException: com.
  2. python精要(75)-turtle(5)
  3. Redis Lua脚本实现原子性操作
  4. 【华为大咖分享】5.交付在云端-全云DevOps研发实践(后附PPT下载地址)
  5. Python 中的黑暗角落(一):理解 yield 关键字
  6. 蓝牙耳机怎么换电池?
  7. 腾讯进军播放器,QQ影音能否撼动暴风影音?
  8. Hi3519V101 开发环境搭建
  9. 计算机桌面分页,你的电脑桌面还会一团糟吗?这款软件可以帮你整理文件
  10. 百度开放大数据平台接口,传统企业看到了新曙光。
  11. 【写博客常用】x86,x64,arm都是什么
  12. opencv 大图中找小图,并点击小图
  13. etc通行费发票怎么打印?通行费发票打印步骤
  14. ZigBee无线点灯示例
  15. CactiEZ 中文版V10.1安装使用以及139邮箱短信报警设置
  16. 学计算机等于写代码吗?计算机专业到底学什么?
  17. oracle10g创建数据库的方法
  18. jQuery中实现,datatable后台数据获取与前端分页展示
  19. python使用微软公司语音识别功能,进行语音识别
  20. 防反接保护电路及功耗计算

热门文章

  1. 最先进的图像分类算法:FixEfficientNet-L2
  2. 基于OpenCV的实战:轮廓检测(附代码解析)
  3. SPI flash配置
  4. linux文件时间属性的详解
  5. 《设计模式 系列》- 面向对象六大原则
  6. MySQL数据库MyISAM存储引擎转为Innodb
  7. 关于VC中的Timer
  8. 利用***+nat解决客户voip被封锁的问题
  9. [文摘20070307]英语表示“走”的20种形式
  10. php 怎么分布式,php分布式怎么部署