HDU3686 Traffic Real Time Query System 题解
题目
City C is really a nightmare of all drivers for its traffic jams. To solve the traffic problem, the mayor plans to build a RTQS (Real Time Query System) to monitor all traffic situations. City C is made up of N crossings and M roads, and each road connects two crossings. All roads are bidirectional. One of the important tasks of RTQS is to answer some queries about route-choice problem. Specifically, the task is to find the crossings which a driver MUST pass when he is driving from one given road to another given road.
输入格式
There are multiple test cases.
For each test case:
The first line contains two integers \(N\) and \(M\), representing the number of the crossings and roads.
The next M lines describe the roads. In those M lines, the i th line (i starts from 1)contains two integers \(X_i\) and \(Y_i\), representing that road i connects crossing \(X_i\) and \(Y_i\) (\(X_i≠Y_i\)).
The following line contains a single integer Q, representing the number of RTQs.
Then Q lines follows, each describing a RTQ by two integers \(S\) and \(T(S≠T)\) meaning that a driver is now driving on the roads and he wants to reach roadt . It will be always at least one way from roads to roadt.
The input ends with a line of “0 0”.
Please note that: \(0< N \le 10000\), \(0 < M \le 100000\), \(0 < Q \le 10000\), \(0 < X_i\),\(Y_i \le N\), \(0 < S,T \le M\)
输出格式
For each RTQ prints a line containing a single integer representing the number of crossings which the driver MUST pass.
样例输入
5 6
1 2
1 3
2 3
3 4
4 5
3 5
2
2 3
2 4
0 0
样例输出
0
1
题解
题目大意:
输出两条边之间必须经过的点
这道题其实没有什么思维难度, 显然先缩点, 求lca即可.
主要就是调起来很麻烦, 而且起点和终点不是点是边.
tarjon缩点, 倍增求lca
代码
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 1e4 + 5, M = 1e5 + 5, Lg = 25;
int n, m, qn, tot, head[2][N << 1], top, sta[N], dfsc, dfn[N], low[N], dccCnt, root, bel[N], eb[M], fa[N << 1][Lg], dep[N << 1], id[N];
bool cut[N], vis[N << 1];
vector<int> dcc[N];
struct Edge { int to, nxt, id; } edges[M << 2];
inline void add(int type, int from, int to, int eid) {
edges[++tot] = (Edge){to, head[type][from], eid}, head[type][from] = tot;
}
void tarjan(int x) {
dfn[x] = low[x] = ++dfsc;
sta[++top] = x;
if (x == root && head[0][x] == 0)
return dcc[++dccCnt].push_back(x);
int son = 0;
for (int i = head[0][x]; i; i = edges[i].nxt) {
int y = edges[i].to;
if (!dfn[y]) {
tarjan(y);
low[x] = min(low[x], low[y]);
if (dfn[x] <= low[y]) {
son++;
if (x != root || son > 1) cut[x] = 1;
dccCnt++;
while(1){
int z = sta[top--];
dcc[dccCnt].push_back(z);
if (z == y) break;
}
dcc[dccCnt].push_back(x);
}
} else low[x] = min(low[x], dfn[y]);
}
}
void dfs(int x, int fat, int depth) {
vis[x] = 1, fa[x][0] = fat, dep[x] = depth;
for (int i = 1; i <= 15; i++) fa[x][i] = fa[fa[x][i - 1]][i - 1];
for (int i = head[1][x]; i; i = edges[i].nxt) {
int y = edges[i].to;
if (vis[y]) continue;
dfs(y, x, depth + 1);
}
}
int lca(int x, int y) {
if (dep[x] < dep[y]) swap(x, y);
for (int i = 15; i >= 0; i--)
if (dep[fa[x][i]] >= dep[y]) x = fa[x][i];
if (x == y) return x;
for (int i = 15; i >= 0; i--)
if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
return fa[x][0];
}
int main() {
while (1) {
scanf("%d%d", &n, &m);
if (n == 0 && m == 0) break;
tot = dfsc = dccCnt = top = 0;
memset(head, 0, sizeof(head));
memset(dfn, 0, sizeof(dfn));
memset(low, 0, sizeof(low));
memset(cut, 0, sizeof(cut));
for (int x, y, i = 1; i <= m; i++) {
scanf("%d%d", &x, &y);
add(0, x, y, i), add(0, y, x, i);
}
for (int i = 1; i <= n; i++) dcc[i].clear();
for (int i = 1; i <= n; i++)
if (!dfn[i]) tarjan(root = i);
int now = dccCnt;
for (int i = 1; i <= n; i++)
if (cut[i]) id[i] = ++now;
for (int i = 1; i <= dccCnt; i++) {
for (int j = 0; j < dcc[i].size(); j++) {
int x = dcc[i][j];
if (cut[x]) add(1, id[x], i, 0), add(1, i, id[x], 0);
bel[x] = i;
}
for (int j = 0; j < dcc[i].size(); j++)
for (int k = head[0][dcc[i][j]]; k; k = edges[k].nxt) if (bel[edges[k].to] == i) eb[edges[k].id] = i;
}
memset(dep, 0, sizeof(dep));
memset(fa, 0, sizeof(fa));
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= now; i++) if (!vis[i]) dfs(i, 0, 1);
scanf("%d", &qn);
for (int x, y; qn--;) {
scanf("%d%d", &x, &y);
x = eb[x], y = eb[y];
if (x == y) puts("0");
else printf("%d\n", (dep[x] + dep[y] - 2 * dep[lca(x, y)]) / 2);
}
}
return 0;
}
HDU3686 Traffic Real Time Query System 题解的更多相关文章
- UVALive-4839 HDU-3686 Traffic Real Time Query System 题解
题目大意: 有一张无向连通图,问从一条边走到另一条边必定要经过的点有几个. 思路: 先用tarjan将双连通分量都并起来,剩下的再将割点独立出来,建成一棵树,之后记录每个点到根有几个割点,再用RMQ求 ...
- CH#24C 逃不掉的路 和 HDU3686 Traffic Real Time Query System
逃不掉的路 CH Round #24 - 三体杯 Round #1 题目描述 现代社会,路是必不可少的.任意两个城镇都有路相连,而且往往不止一条.但有些路连年被各种XXOO,走着很不爽.按理说条条大路 ...
- HDU3686 Traffic Real Time Query System
P.S.此题无代码,只有口胡,因为作者码炸了. 题目大意 给你一个有 \(n\) 个点, \(m\) 条边的无向图,进行 \(q\) 次询问,每次询问两个点 \(u\) \(v\),输出两个点的之间的 ...
- HDU 3686 Traffic Real Time Query System (图论)
HDU 3686 Traffic Real Time Query System 题目大意 给一个N个点M条边的无向图,然后有Q个询问X,Y,问第X边到第Y边必需要经过的点有多少个. solution ...
- HDU 3686 Traffic Real Time Query System(双连通分量缩点+LCA)(2010 Asia Hangzhou Regional Contest)
Problem Description City C is really a nightmare of all drivers for its traffic jams. To solve the t ...
- HDU3686 Traffic Real Time Query【缩点+lca】
题目 City C is really a nightmare of all drivers for its traffic jams. To solve the traffic problem, t ...
- Traffic Real Time Query System 圆方树+LCA
题目描述 City C is really a nightmare of all drivers for its traffic jams. To solve the traffic problem, ...
- Traffic Real Time Query System,题解
题目链接 题意: 问从一条边到另一条边的必经点. 分析: 首先,问必经点,当然是要点双缩点(圆方树)啦,关键是把边映射到哪一点上,其实直接放在某联通分量的方点上就行,但是这个点并不好找,所以我们考虑一 ...
- HDU Traffic Real Time Query System
题目大意是:对于(n, m)的图,给定边a, b查询从a到b要经过的割点的最少数目. 先tarjan算法求双连通然后缩点,即对于每个割点将周围的每个双连通看成一个点与之相连.然后求解LCA即可,距离d ...
随机推荐
- PAT 德才论
宋代史学家司马光在<资治通鉴>中有一段著名的“德才论”:“是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人.凡取人之术,苟不得圣人,君子而与之,与其得小人,不若得愚人 ...
- lambda表达式操作DataTable番外篇
using System;using System.Collections.Generic;using System.Data;using System.Linq;using System.Text; ...
- Tomcat的8080端口被占用无法启动Tomcat怎么办?
一招解决Tomcat的8080端口被占用 打开tomcat的bin目录在,找到startup.bat,用记事本编辑startup.bat,在第一行加入 set JAVA_HOME=C:\Program ...
- 头条面试居然跟我扯了半小时的Semaphore
一个长头发.穿着清爽的小姐姐,拿着一个崭新的Mac笔记本向我走来,看着来势汹汹,我心想着肯定是技术大佬吧!但是我也是一个才华横溢的人,稳住我们能赢. 面试官:看你简历上有写熟悉并发编程,Semapho ...
- DML_Data Modification_UPDATE
DML_Data Modification_UPDATE写不进去,不能专注了...... /* */ ------------------------------------------------- ...
- MSSQL2008下备份好的*.bak--->>>恢复到--->>>MSSQL2014(解决办法)
MSSQL2008下备份好的*.bak--->>>恢复到--->>>MSSQL2014(解决办法) 在进行CTE训练时(同时也要理解下窗口函数的应用),发现不能继续 ...
- (二)HttpClient Post请求
原文链接:https://blog.csdn.net/justry_deng/article/details/81042379 POST无参: /** * POST---无参测试 * * @date ...
- SpringMVC的url-pattern配置及原理剖析
SpringMVC的url-pattern配置及原理剖析 xml里面配置标签: <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc./ ...
- Beta冲刺--冲刺总结
这个作业属于哪个课程 软件工程 (福州大学至诚学院 - 计算机工程系) 这个作业要求在哪里 Beta 冲刺 这个作业的目标 Beta冲刺--冲刺总结 作业正文 如下 其他参考文献 ... Beta冲刺 ...
- 定时任务Cron
Linux系统中的定时任务cron,一个很实际很有效很简单的一个工作,在日常的生产环境中,会被广泛使用的一个组件.通过设置时间.执行的脚本等内容,能够让系统自动的执行相关任务,很是方便. cron定时 ...