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牧场",选择"设为星标"技术干货每日送达 点 ...
随机推荐
- APP分享多张图片到微信和朋友圈
产品需求: 微信分享多图至好友,朋友圈.由于微信禁用了分享9图至朋友圈功能,这里分享微信只是将图片保存至本地,具体让用户手动分享. 问题分析: 微信没有提供分享多图的SDK,因此我们实现调用系统自带的 ...
- Java 获取微信小程序二维码(可以指定小程序页面 与 动态参数)
一.准备工作 微信公众平台接口调试工具 小程序的唯一标识(appid) 小程序的密钥(secret) 二.获取access_token 打开微信公众平台接口调试工具,在参数列表中输入小程序的appid ...
- 07 . 前端工程化(ES6模块化和webpack打包)
模块化规范 传统开发模式主要问题 /* 1. 命名冲突 2. 文件依赖 */ 通过模块化解决上述问题 /* 模块化就是把单独的一个功能封装在一个模块(文件)中,模块之间相互隔离, 但是可以通过特定的接 ...
- C++运行时类型判断dynamic_cast和typeid
dynamic_cast dynamic_cast < Type-id > ( expression ) dynamic_cast<类型>(变量) 在运行期间检测类型转换是否安 ...
- C语言中的const用法
Const是什么? const是一个C语言的关键字,它限定一个变量不允许被改变.使用const在一定程度上可以提高程序的健壮性,另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程 ...
- 如何调整MathType公式的字体大小
作为一名理科生,想必大家都在为编辑公式而烦恼,在Word中要想完美插入公式,还真不是那么简单的.首先要使用专业的公式编辑器MathType,其次还要对公式的大小进行修改,这样才能看起来是相融合的文章. ...
- input[type=file] 样式美化,input上传按钮美化
<style>.file { position: relative; display: inline-block; background: #D0EEFF; border: 1px sol ...
- 使用celery异步发送短信
目录 1.使用celery异步发送短信 1.1在celery_task/mian.py中添加发送短信函数 1.2在verifcations/views.py中添加celery发送短信视图函数 1.3 ...
- 【???】今天上午的考试题——区间dp和字符串/线性筛的综合应用
T3还没有打出来,就先放两道. ---------------------------------------------------------- T1:密码破译 温温手下的情报部门截获了一封加密信 ...
- 用FL Studio基础版制作一首完整的电音
电音制作,自然少不了适合做电音的软件,市面上可以进行电音制作的软件不少,可是如果在这些软件中只能选择一款的话,想必多数人会把票投给FL Studio,毕竟高效率是永远不变的真理,今天就让我们来看看如何 ...