AcWing 398. 交通实时查询系统
大型补档计划
只有割点是必行点。
在任意一个点双中,都有分叉没有点交集的两条路径。
所以 v-DCC 缩点。
但是他问的是路径走到另一条路径的必行点。我蒙蔽了,发现自己对无向图双联通分量理解不够。因为一条边必然属于且只属于一个点双联通分量,为什么呢?因为就选这条边的两个点就构成了一个点双联通分量,所以必然存在包含的,并且由于极大性,只属于一个也显然。
缩点后变成一颗树。然后就变成了:在一颗树中,任意两点间有多少个特殊的点(割点?),用 LCA + 树上差分即可。
upd1:顺便提一句,这道题不一定保证联通,可能是森林,所以要多次dfs,但是第一次写我没多次也过了,说明数据较水。
upd2:为啥我uva WA了。
#include <cstdio>
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
const int N = 20005, M = 200005, L = 15;
int n, m, Q, num, newId[N];
int dfn[N], low[N], dfncnt, s[N], c[N], top, cnt, id[M], d[N];
bool vis[N];
int fa[N][L], dep[N];
vector<int> dcc[N], g[N];
bool cut[N];
int head[N], numE = 1;
struct E{
int next, v;
} e[M];
void inline add(int u, int v) {
e[++numE] = (E) { head[u], v };
head[u] = numE;
}
void tarjan(int u, int rt) {
dfn[u] = low[u] = ++dfncnt;
s[++top] = u;
if (u == rt && !head[u]) {
dcc[++cnt].push_back(u);
return;
}
int flag = 0;
for (int i = head[u]; i; i = e[i].next) {
int v = e[i].v;
if (!dfn[v]) {
tarjan(v, rt); low[u] = min(low[u], low[v]);
if (low[v] >= dfn[u]) {
flag++;
if (u != rt || flag > 1) cut[u] = true;
int y; ++cnt;
do {
y = s[top--];
dcc[cnt].push_back(y);
} while (y != v);
dcc[cnt].push_back(u);
}
} else low[u] = min(low[u], dfn[v]);
}
}
void dfs(int u) {
vis[u] = true;
for (int i = 1; i < L && fa[u][i - 1]; i++)
fa[u][i] = fa[fa[u][i - 1]][i - 1];
if (u > cnt) d[u]++;
for (int i = 0; i < g[u].size(); i++) {
int v = g[u][i];
if (v == fa[u][0]) continue;
fa[v][0] = u, dep[v] = dep[u] + 1, d[v] = d[u];
dfs(v);
}
}
int lca(int x, int y) {
if (dep[x] < dep[y]) swap(x, y);
for (int i = L - 1; ~i; i--)
if (dep[x] - (1 << i) >= dep[y]) x = fa[x][i];
if (x == y) return x;
for (int i = L - 1; ~i; i--)
if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
return fa[x][0];
}
int main() {
while (scanf("%d%d", &n, &m), n || m) {
for (int i = 1, x, y; i <= m; i++) {
scanf("%d%d", &x, &y);
add(x, y); add(y, x);
}
for (int i = 1; i <= n; i++) if (!dfn[i]) tarjan(i, i);
num = cnt;
for (int i = 1; i <= n; i++) if (cut[i]) newId[i] = ++num;
for (int i = 1; i <= cnt; i++) {
for (int j = 0; j < dcc[i].size(); j++) {
int x = dcc[i][j];
if (cut[x]){
g[newId[x]].push_back(i);
g[i].push_back(newId[x]);
}
c[x] = i;
}
for (int j = 0; j < dcc[i].size(); j++) {
int x = dcc[i][j];
for (int k = head[x]; k; k = e[k].next) {
int v = e[k].v;
if (c[v] == i) id[k >> 1] = i;
}
}
}
for (int i = 1; i <= num; i++) if (!vis[i]) dfs(i);
scanf("%d", &Q);
while (Q--) {
int a, b; scanf("%d%d", &a, &b);
a = id[a], b = id[b];
int p = lca(a, b);
printf("%d\n", d[fa[a][0]] - d[fa[p][0]] + d[fa[b][0]] - d[p]);
}
numE = 1;
memset(cut, false, sizeof cut);
memset(newId, 0, sizeof newId);
memset(c, 0, sizeof c);
memset(head, 0, sizeof head);
memset(dfn, 0, sizeof dfn);
memset(vis, false, sizeof vis);
memset(id, 0, sizeof id);
memset(fa, 0, sizeof fa);
for (int i = 1; i <= num; i++) g[i].clear();
for (int i = 1; i <= cnt; i++) dcc[i].clear();
dfncnt = cnt = 0;
}
return 0;
}
AcWing 398. 交通实时查询系统的更多相关文章
- 实时查询系统架构:spark流式处理+HBase+solr/ES查询
最近要做一个实时查询系统,初步协商后系统的框架 1.流式计算:数据都给spark 计算后放回HBase 2.查询:查询采用HBase+Solr/ES
- Windows系统CPU和内存状态实时查询(Java)
一.背景 需要查询Windows服务器的CPU和内存状态. Linux系统查询CPU和内存状态很简单,一个top命令搞定,Windows就稍微麻烦一些了. 经过资料查找,发现jdk目前不能直接查询系统 ...
- 转: 透过CAT,来看分布式实时监控系统的设计与实现
评注: 开源的分布式监控系统 转:http://www.infoq.com/cn/articles/distributed-real-time-monitoring-and-control-syste ...
- 基于三星ARM9(S3C2410)的交通违章抓拍系统的开发
ARM9的交通违章抓拍系统的开发 ARM9的交通违章抓拍系统的开发 智能交通系统(ITS)将先进的信息技术.数据通讯传输技术.电子控制技术.计算机处理技术等应用于交通运输行业,从而实现各种运输方式 ...
- 透过CAT,来看分布式实时监控系统的设计与实现
2011年底,我加入大众点评网,出于很偶然的机会,决定开发CAT,为各个业务线打造分布式实时监控系统,CAT的核心概念源自eBay闭源系统CAL----eBay的几大法宝之一. 在当今互联网时代,业务 ...
- 基于Impala平台打造交互查询系统
本文来自网易云社区 原创: 蒋鸿翔 DataFunTalk 本文根据网易大数据蒋鸿翔老师DataFun Talk--"大数据从底层处理到数据驱动业务"中分享的<基于Impal ...
- 实时查询引擎 - Facebook Presto 介绍与应用
1. Presto 是什么 Facebook presto是什么,继Facebook创建了HIVE神器后的又一以SQL语言作为接口的分布式实时查询引擎,可以对PB级的数据进行快速的交互式查询.它支 ...
- Druid:一个用于大数据实时处理的开源分布式系统——大数据实时查询和分析的高容错、高性能开源分布式系统
转自:http://www.36dsj.com/archives/28590 Druid 是一个用于大数据实时查询和分析的高容错.高性能开源分布式系统,旨在快速处理大规模的数据,并能够实现快速查询和分 ...
- PB级数据实时查询,滴滴Elasticsearch多集群架构实践
PB级数据实时查询,滴滴Elasticsearch多集群架构实践 mp.weixin.qq.com 点击上方"IT牧场",选择"设为星标"技术干货每日送达 点 ...
随机推荐
- nginx&http 第三章 ngx 事件http 初始化1
在 http 配置块中,我们配置了 http 连接相关的信息,HTTP 框架也正是从这里启动的 在 nginx 初始化的过程中,执行了 ngx_init_cycle 函数,其中进行了配置文件解析,调用 ...
- redis重点ppt
- C++ Split string into vector<string> by space(转)
c++中没有这么方便的实现,但也有很多的方法能实现这个功能,下面列出五种常用的实现的方法,请根据需要选择,个人觉得前三种使用起来比较方便,参见代码如下: #include <vector> ...
- 微服务通信之feign的配置隔离
前言 由上文我们知道针对某一个Feign接口,我们可以给他设置特定的配置类.那如果现在有一个服务,我们只想对A服务配置一个拦截器拦截请求而不影响其他服务,那应该怎么做呢? 一.feign接口配置 由前 ...
- 利用火焰图分析ceph pg分布
前言 性能优化大神Brendan Gregg发明了火焰图来定位性能问题,通过图表就可以发现问题出在哪里,通过svg矢量图来查看性能卡在哪个点,哪个操作占用的资源最多 在查看了原始数据后,这个分析的原理 ...
- kali 2020.1 更新源,并安装docker
先说一句浙大牛逼!!!装个docker折腾了半天,测了半天只有浙大的更新源能用,完美不报错!清华阿里什么的更新源都是渣渣. deb http://mirrors.zju.edu.cn/kali kal ...
- CVE-2020-1938复现
一.漏洞描述 Tomcat是Apache开源组织开发的用于处理HTTP服务的项目,两者都是免费的,都可以做为独立的Web服务器运行.Apache Tomcat服务器存在文件包含漏洞,攻击 ...
- 如何查看CDR文件是出自哪个版本?
如何才能知道某个cdr文件用哪个版本的CorelDRAW软件打开?网上CorelDRAW软件有很多版本,都不知该下哪个了?这是我听到大家问道最多的问题,这是因为CDR低版本软件打不开高版本文件. 方法 ...
- SQL server分页的四种方法(算很全面了)
这篇博客讲的是SQL server的分页方法,用的SQL server 2012版本.下面都用pageIndex表示页数,pageSize表示一页包含的记录.并且下面涉及到具体例子的,设定查询第2 ...
- 牛客练习赛67 D牛妹爱数列 题解(dp)
题目链接 题目大意 给你一个长为n的01串,要你进行最少的操作使得这01串变成全为0,求最少操作次数 有两种不同类型的操作 1:翻转一个前缀 2:单调翻转一个元素 题目思路 居然是一个dp,标程讲的很 ...