HDU 3686 Traffic Real Time Query System (图论)
HDU 3686 Traffic Real Time Query System
题目大意
给一个N个点M条边的无向图,然后有Q个询问X,Y,问第X边到第Y边必需要经过的点有多少个。
solution
显然园方树+tarjan求LCA,然后求两条边之间的点
必经的点的数量就是圆点的数量,然后进行分类讨论
- 若\(LCA\)为圆点:
那么其中一个点到\(LCA\)的圆点数量为\((deep[x] - deep[lca])/2\),因为\(LCA\)为圆点被算了两遍,所以要-1 - 若\(LCA\)为方点:
那么其中一个点到\(LCA\)的圆点数量为\((deep[x] - deep[lca]- 1)/2\),那么两个点之间的圆点数量就是\((deep[x] + deep[y] - 2 * deep[lca])- 1\)
由此可见,两种情况算下来,答案的式子是一样的,所以直接上板子算答案就行了,这道题的代码还是比较考验码力的……
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
#define v e[i].to
const int maxn=10000+3,maxe=100000+3;
int n,m,tot,head[maxn],h[2*maxn],js,dfs_clock,deep[2*maxn],father[2*maxn];
int bcc_cnt,sta[maxn],top,dfn[maxn],low[maxn];
bool vis[2*maxn];
struct edge{
int from,to,next;
}e[2*maxe],ed[2*maxe];
inline void Add(int a,int b){//原图
e[++tot].from=a;
e[tot].to=b;
e[tot].next=head[a];
head[a]=tot;
}
inline void Add2(int a,int b){//圆方树
ed[++js].from=a;
ed[js].to=b;
ed[js].next=h[a];
h[a]=js;
}
inline void tarjan(int u){
low[u]=dfn[u]=++dfs_clock;
sta[++top]=u;
for(int i=head[u];i;i=e[i].next){
if(dfn[v]) low[u]=min(low[u],dfn[v]);
else{
tarjan(v);
low[u]=min(low[v],low[u]);
if(low[v]==dfn[u]){
++bcc_cnt;
int temp;
do{
temp=sta[top];
top--;
Add2(n+bcc_cnt,temp);
Add2(temp,n+bcc_cnt);
}while(temp!=v);
Add2(u,n+bcc_cnt);
Add2(n+bcc_cnt,u);
}
}
}
}
inline void init(){
tot=0; js=0; top=0; dfs_clock=0; bcc_cnt=0;
memset(head,0,sizeof(head));
memset(e,0,sizeof(e));
memset(h,0,sizeof(h));
memset(ed,0,sizeof(ed));
memset(sta,0,sizeof(sta));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(deep,0,sizeof(deep));
memset(vis,0,sizeof(vis));
memset(father,0,sizeof(father));
memset(sta,0,sizeof(sta));
}
inline void dfs(int x){
vis[x]=1;
for(int i=h[x];i;i=ed[i].next){
int now=ed[i].to;
if(vis[now]) continue;
deep[now]=deep[x]+1;
father[now]=x;
dfs(now);
}
}
inline int find(int a,int b){//非倍增也可
if(deep[a]<deep[b]) swap(a,b);
while(deep[a]>deep[b]) a=father[a];
while(a!=b){
a=father[a];
b=father[b];
}
return a;
}
inline int len(int a,int b){
int lca=find(a,b);
return (deep[a]+deep[b]-2*deep[lca])/2-1;
}
int main(){
while(1){
scanf("%d%d",&n,&m);
if(n==0&&m==0) return 0;
init();
for(int i=1;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
Add(x,y);
Add(y,x);
}
for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
for(int i=1;i<=n+bcc_cnt;i++) if(!vis[i]) dfs(i);
int t;
scanf("%d",&t);
while(t--){
int x,y;
scanf("%d%d",&x,&y);
int a=e[x*2].from,b=e[x*2].to,c=e[y*2].from,d=e[y*2].to; //枚举节点
printf("%d\n",max(max(len(b,d),len(a,d)),max(len(b,c),len(a,c))));
}
}
}
提交语言GCC、GCC、GCC!!!
md重要的事情说三遍,淦……
HDU 3686 Traffic Real Time Query System (图论)的更多相关文章
- 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 ...
- hdu 3686 Traffic Real Time Query System 点双两通分量 + LCA。这题有重边!!!
http://acm.hdu.edu.cn/showproblem.php?pid=3686 我要把这题记录下来. 一直wa. 自己生成数据都是AC的.现在还是wa.留坑. 我感觉我现在倒下去床上就能 ...
- HDU 3686 Traffic Real Time Query System(点双连通)
题意 给定一张 \(n\) 个点 \(m\) 条边的无向图,\(q\) 次询问,每次询问两边之间的必经之点个数. 思路 求两点之间必经之边的个数用的是边双缩点,再求树上距离.而对比边双和点双之 ...
- 【HDOJ】3686 Traffic Real Time Query System
这题做了几个小时,基本思路肯定是求两点路径中的割点数目,思路是tarjan缩点,然后以割点和连通块作为新节点见图.转化为lca求解.结合点——双连通分量与LCA. /* 3686 */ #includ ...
- 【Targan+LCA】HDU 3686 Traffic Real Time Query
题目内容 洛谷链接 给出一个\(n\)个节点,\(m\)条边的无向图和两个节点\(s\)和\(t\),问这两个节点的路径中有几个点必须经过. 输入格式 第一行是\(n\)和\(m\). 接下来\(m\ ...
- CH#24C 逃不掉的路 和 HDU3686 Traffic Real Time Query System
逃不掉的路 CH Round #24 - 三体杯 Round #1 题目描述 现代社会,路是必不可少的.任意两个城镇都有路相连,而且往往不止一条.但有些路连年被各种XXOO,走着很不爽.按理说条条大路 ...
- HDU3686 Traffic Real Time Query System 题解
题目 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 - 3686
https://vjudge.net/problem/HDU-3686 点双啊,就是在求割顶的时候,另外用一个栈来存一些边 在遍历u点出发的边时,遇到树边或反向边(u,v)就把此边加入栈(可能要记一下 ...
随机推荐
- Redis企业级数据备份与恢复方案
一.持久化配置 RBD和AOF建议同时打开(Redis4.0之后支持) RDB做冷备,AOF做数据恢复(数据更可靠) RDB采取默认配置即可,AOF推荐采取everysec每秒策略 AOF和RDB还不 ...
- JDBC连接泄露问题的排查过程总结
当前使用的Spring JDBC版本是5.0.0.RC1,HikariCP版本是3.1.0. 今天测试同学反馈在前端页面点击次数多了,就报500错误,数据显示不出来.于是我在后台服务日志中观察发现Hi ...
- 通知!Symantec品牌证书已正式更名为Digicert
尊敬的合作伙伴和客户: 您好! 2017年8月2日,CA认证机构Digicert宣布正式收购 Symantec 安全认证业务.为此,Digicert宣布从2020年4月30日起,停止使用与赛门铁克(S ...
- Cookie默认不设置path时,哪些请求会携带cookie数据
默认不设置path的时候,只会在请求和servlet同路径的情况下才会携带cookie中存储的数据,包含同级目录和下级目录 例如: 在http://localhost:8080/day01/test/ ...
- 问题解决:psql: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
错误提示: psql: could not connect to server: No such file or directory Is the server running locally and ...
- 十几万条数据的表中,基于帝国cms 。自己亲身体验三种批量更新数据的方法,每一种的速度是什么样的
需求是 上传Excel 读取里面的数据.根据Excel中某一个字段,与数据表中的一个字段的唯一性.然后把 Excel表中数据和数据库表中数据一次更改.本次测试一次更新31条数据. 本次测试基于帝国cm ...
- String Problem(模板)【最短路】
String Problem 题目链接(点击) Boy Valera likes strings. And even more he likes them, when they are identic ...
- Java——int、double型数组常用操作工具类
学了数组之后,感觉有好多操作需要经常去写,很不方便,因此自己做了一个工具类,方便调用,方法可能不全,希望大家可以添加,让我使用也方便一点儿. public class ArrayUtils { //求 ...
- fastjson对String、JSONObject、JSONArray相互转换
String——>>>JSONArray String st = "[{name:Tim,age:25,sex:male},{name:Tom,age:28,sex:mal ...
- IP组网实验(使用Cisco Packet Tracer路由器模拟软件)
最近计网课讲到了以太网,第二个计网实验就是IP组网实验.这个实验主要使用了netsim这个路由器模拟软件.怎奈mac上没有,于是用Cisco Packet Tracer进行了一次模拟(其实就是实验中的 ...