AcWing 397. 逃不掉的路(边双连通分量缩点成树 + 树链剖分乱搞)
整理的算法模板合集: 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. 逃不掉的路(边双连通分量缩点成树 + 树链剖分乱搞)相关推荐
- 为什么劝你别去创业?大抵逃不掉这 101 个问题
2016年底,当我的同事小白建议把我的思考整理成书的时候,大家都是沉默的.也许大家觉得创业这个话题成书是有难度的. 所以在这里我要感谢蓝狮子和浙江大学出版社,他们给了我这个机会.而在整理和思考的过程中 ...
- 哥几个又来看啦,进来吧逃不掉的(Linux精中之精)
前言:天天敲代码主播的头都要炸了,估计拐友们也炸的一批,但咩办法学这个逃不掉的,乖乖敲吧,但为了让拐友们不是那么的痛苦,主播通宵给你们整理了Liunx精中之精的代码,保证外星人来了都能看懂.(ps:记 ...
- 逃不掉的小球-第10届蓝桥杯Scratch国赛真题第1题
[导读]:超平老师计划推出Scratch蓝桥杯真题解析100讲,这是超平老师解读Scratch蓝桥真题系列的第22讲. 第10届蓝桥杯青少年组国赛于2019年5月25日举行,形式为线下考试,考生自带电 ...
- 逃不掉的是回忆,忘不了的是曾经:伤感日志
逃不掉的是回忆,忘不了的是曾经:伤感日志 - 逃不掉的是回忆,忘不了的是曾经:伤感日志 [我以为我会是唯一的唯一] 开始,Start. 或许是我太天真的,曾经认为我是唯一的唯一. 可是现实一次次把我打 ...
- 几度苍凉的伤感独特日志发布:想要逃,却怎么也逃不掉
几度苍凉的伤感独特日志发布:想要逃,却怎么也逃不掉 - 几度苍凉的伤感独特日志发布:想要逃,却怎么也逃不掉 当你问我:你会和我结婚吗?我不知道.当你问我:你会来看我吗?我不知道. 当你问我:四年后我们 ...
- P4320-道路相遇,P5058-[ZJOI2004]嗅探器【圆方树,LCA】
两题差不多就一起写了 P4320-道路相遇 题目链接:https://www.luogu.com.cn/problem/P4320 题目大意 nnn个点mmm条边的一张图,qqq次询问两个点之间路径的 ...
- 双路cpu比单路强多少_电源单路好还是双路好?电脑电源单路和双路12V详细区别对比...
在一些比较大功率的电源中,经常可以看到分为单路12V和双路甚至是多路12V两种规格.那么,电源单路好还是双路好呢,很多网友搞不清这个问题.下面"脚本之家"以最通俗易懂的描述,带大家 ...
- (揭秘监控技术)《潜行追踪》:FBI 给你28天,你也逃不掉,中国版呢?
上周末,雷锋网编辑小李经人推荐,把美版<Hunted:潜行追踪>第一季刷完了. 这部剧为什么这么好看?和网络安全又有什么联系?要想知道这些问题的答案,先来简单介绍一下: <潜行追踪& ...
- 逃不掉的职场中年危机?
[从发生在你我身边的裁员潮说起] 前段时间有位互联网公司的人力朋友M给我转了张图片,我一看还挺逗: 总之,人脉少的开滴滴,人脉多的做微商. 我给她发了个哭笑不得的表情包,她却有些严肃地回我: &quo ...
最新文章
- java.lang.ClassNotFoundException: com.mysql.jdbc.Driver 解决方法 java.lang.ClassNotFoundException: com.
- python精要(75)-turtle(5)
- Redis Lua脚本实现原子性操作
- 【华为大咖分享】5.交付在云端-全云DevOps研发实践(后附PPT下载地址)
- Python 中的黑暗角落(一):理解 yield 关键字
- 蓝牙耳机怎么换电池?
- 腾讯进军播放器,QQ影音能否撼动暴风影音?
- Hi3519V101 开发环境搭建
- 计算机桌面分页,你的电脑桌面还会一团糟吗?这款软件可以帮你整理文件
- 百度开放大数据平台接口,传统企业看到了新曙光。
- 【写博客常用】x86,x64,arm都是什么
- opencv 大图中找小图,并点击小图
- etc通行费发票怎么打印?通行费发票打印步骤
- ZigBee无线点灯示例
- CactiEZ 中文版V10.1安装使用以及139邮箱短信报警设置
- 学计算机等于写代码吗?计算机专业到底学什么?
- oracle10g创建数据库的方法
- jQuery中实现,datatable后台数据获取与前端分页展示
- python使用微软公司语音识别功能,进行语音识别
- 防反接保护电路及功耗计算