大型补档计划

题目链接

只有割点是必行点。

在任意一个点双中,都有分叉没有点交集的两条路径。

所以 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. 交通实时查询系统的更多相关文章

  1. 实时查询系统架构:spark流式处理+HBase+solr/ES查询

    最近要做一个实时查询系统,初步协商后系统的框架 1.流式计算:数据都给spark 计算后放回HBase 2.查询:查询采用HBase+Solr/ES

  2. Windows系统CPU和内存状态实时查询(Java)

    一.背景 需要查询Windows服务器的CPU和内存状态. Linux系统查询CPU和内存状态很简单,一个top命令搞定,Windows就稍微麻烦一些了. 经过资料查找,发现jdk目前不能直接查询系统 ...

  3. 转: 透过CAT,来看分布式实时监控系统的设计与实现

    评注: 开源的分布式监控系统 转:http://www.infoq.com/cn/articles/distributed-real-time-monitoring-and-control-syste ...

  4. 基于三星ARM9(S3C2410)的交通违章抓拍系统的开发

    ARM9的交通违章抓拍系统的开发   ARM9的交通违章抓拍系统的开发 智能交通系统(ITS)将先进的信息技术.数据通讯传输技术.电子控制技术.计算机处理技术等应用于交通运输行业,从而实现各种运输方式 ...

  5. 透过CAT,来看分布式实时监控系统的设计与实现

    2011年底,我加入大众点评网,出于很偶然的机会,决定开发CAT,为各个业务线打造分布式实时监控系统,CAT的核心概念源自eBay闭源系统CAL----eBay的几大法宝之一. 在当今互联网时代,业务 ...

  6. 基于Impala平台打造交互查询系统

    本文来自网易云社区 原创: 蒋鸿翔 DataFunTalk 本文根据网易大数据蒋鸿翔老师DataFun Talk--"大数据从底层处理到数据驱动业务"中分享的<基于Impal ...

  7. 实时查询引擎 - Facebook Presto 介绍与应用

    1. Presto 是什么   Facebook presto是什么,继Facebook创建了HIVE神器后的又一以SQL语言作为接口的分布式实时查询引擎,可以对PB级的数据进行快速的交互式查询.它支 ...

  8. Druid:一个用于大数据实时处理的开源分布式系统——大数据实时查询和分析的高容错、高性能开源分布式系统

    转自:http://www.36dsj.com/archives/28590 Druid 是一个用于大数据实时查询和分析的高容错.高性能开源分布式系统,旨在快速处理大规模的数据,并能够实现快速查询和分 ...

  9. PB级数据实时查询,滴滴Elasticsearch多集群架构实践

    PB级数据实时查询,滴滴Elasticsearch多集群架构实践  mp.weixin.qq.com 点击上方"IT牧场",选择"设为星标"技术干货每日送达 点 ...

随机推荐

  1. shell编程之俄罗斯方块

    按键获取: 向上  ^[[A 向下  ^[[B 向左  ^[[D 向右  ^[[C 其中  ^[为ESC键. 按键获取的具体shell代码如下所示: #! /bin/bash GetKey() { a ...

  2. POSIX信号量与互斥锁实现生产者消费者模型

    posix信号量 Link with -lpthread. sem_t *sem_open(const char *name, int oflag);//打开POSIX信号量 sem_t *sem_o ...

  3. 关于点击弹框外部区域弹框关闭的交互处理(前端JS)

    常见需求场景 前端在处理交互的时候,经常遇到这样的场景,点击一个按钮,出现一个弹框,点击外部区域,弹框关闭. 解决方法 思路说明: 1.给弹框的div父级都加个类名,如: 2.在document绑定一 ...

  4. 微信公众号获取openid(php实例)

    微信公众号获取openid 公众号获取openid的方法跟小程序获取openid其实是一样的,只是code获取的方式不一样 小程序获取code: 用户授权登录时调用wx.login即可获取到code ...

  5. netsniff使用

    1 netsniff安装与使用 首先直接下载源码包进行部署 安装一些前置包(安装完成的自动忽略) sudo apt install pkg-config sudo apt install libcli ...

  6. Guitar Pro 7教程之打开播放文件的操作技巧

    前面的章节我们讲过了很多关于Guitar Pro的相关教程,由于最近{cms_selflink page='index' text='Guitar Pro'} 7中文版刚上新没多久,很多玩吉他的小伙伴 ...

  7. 再也不用担心问RecycleView了——面试真题详解

    关于RecycleView,之前我写过一篇比较基础的文章,主要说的是缓存和优化等问题.但是有读者反映问题不够实际和深入.于是,我又去淘了一些关于RecycleView的面试真题,大家一起看看吧,这次的 ...

  8. 关于UILabel标签控件的使用小节

    前段时间一直想停下来,总结一下近期在开发中遇到的一些问题顺便分享一下解决问题的思路和方法,无奈人生就像蒲公英,看似自由却身不由己.太多的时间和精力被占用在新项目的开发和之前项目的维护中,总之一句话外包 ...

  9. 2020.7.19 区间dp阶段测试

    打崩了-- 事先说明,今天没有很在状态,所以题解就直接写在代码注释里的,非常抱歉 T1 颜色联通块 此题有争议,建议跳过 题目描述 N 个方块排成一排,第 i 个颜色为 Ci .定义一个颜色联通块 [ ...

  10. transient关键字的作用以及几个疑问的解决

    目录 1.从Serilizable说到transient 2.序列化属性对象的类需要实现Serilizable接口? 3.不想被序列化的字段怎么办? 4.ArrayList里面的elementData ...