UVA1464 Traffic Real Time Query System
传送门:https://www.luogu.com.cn/problem/UVA1464

看到这道题,求必经的点数,还是无向图。那么妥妥的圆方树。圆方树上的任意两圆点间的路径必定是圆点方点相交错的,对于树上的两点来说,必经的点数就是这两点间简单路径上的圆点的个数。那么这样问题就转化为求树上两点间经过的圆点的个数了。那么我们可以再加一个LCA来解决问题。对于两个圆点,它们的LCA一定是一个方点(当然一个是另一个的祖先时除外)。经过推导可以得出
- ans=(dep[u]+dep[v]-2×dep[LCA(u,v)])/2-1;
然后需要注意的地方就是整个图不一定是全连通的,以及题目中所给的起点终点是两条边,不是点,所以我们把四个顶点都算一遍取最大值。
题本身难度不大,难度在于代码打不出来。。。
代码调了一晚上没调出来结果是数组开小了。。。不说了,还是感谢lc大锅。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
const int maxn=100000+1,maxm=300000+1;
struct Edge{
int next,to;
}edge[maxn<<1];
int head[maxn],len=1;
void Add(int u,int v){
edge[++len].next=head[u];
edge[len].to=v;
head[u]=len;
}
vector<int> G[maxn];
int dfs_clock=0,sta[maxn],top=0,dfn[maxn],low[maxn];
int belong[maxn],dcc_cnt;
bool cut[maxn];
void Tarjan(int u,int fa){
dfn[u]=low[u]=++dfs_clock;
sta[++top]=u;
int son=0;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(!dfn[v]){
son++;
Tarjan(v,fa);
low[u]=min(low[u],low[v]);
if(dfn[u]<=low[v]){
if(u!=fa) cut[u]=1;//习惯性判了个割点,这里不判也没事
dcc_cnt++;
int x;
while(true){
x=sta[top--];
G[dcc_cnt].push_back(x);
G[x].push_back(dcc_cnt);
if(v==x) break;
}
G[dcc_cnt].push_back(u);//一个割点可能同属于多个点双,故不退栈,单独处理
G[u].push_back(dcc_cnt);
}
}
else
low[u]=min(low[u],dfn[v]);
}
if(u==fa&&son>=2) cut[u]=1;//习惯性判了个割点,这里不判也没事
}
int f[maxn][30],dep[maxn];
bool vis[maxn];
void Dfs(int u,int fa){//有毒的倍增法求LCA
dep[u]=dep[fa]+1;
vis[u]=1;
f[u][0]=fa;
for(int i=1;(1<<i)<=dep[u];i++){
f[u][i]=f[f[u][i-1]][i-1];
}
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(v!=fa&&!vis[v]) Dfs(v,u);
}
}
int Lca(int s,int t){
if(dep[s]>dep[t])swap(s,t);
int d=dep[t]-dep[s];
int k=0;
while(d){
if(d&1) t=f[t][k];
k++;
d>>=1;
}
if(s==t) return s;
for(int i=20;i>=0;i--){
if(f[s][i]!=f[t][i])
s=f[s][i],t=f[t][i];
}
return f[s][0];
}
int from[maxn],to[maxn];
void Del(int n){//多组数据,初始化
memset(from,0,sizeof(from));
memset(to,0,sizeof(to));
memset(head,0,sizeof(head));
len=0;
memset(G,0,sizeof(G));
memset(vis,0,sizeof(vis));
memset(cut,0,sizeof(cut));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(f,0,sizeof(f));
memset(dep,0,sizeof(dep));
dcc_cnt=n;//方点从n+1开始编号
top=0;
dfs_clock=0;
}
int Calc(int u,int v){
return (dep[u]+dep[v]-(dep[Lca(u,v)]<<1))/2-1;
}
int solve(int xx,int yy){
return (dep[xx]+dep[yy]-2*dep[Lca(xx,yy)])/2-1;
}
int main(){
int n,m;
while(scanf("%d%d",&n,&m) && n!=0){
if(n==0||m==0) return 0;
Del(n);
int u,v;
for(int i=1;i<=m;i++){
scanf("%d%d",&u,&v);
Add(u,v);
Add(v,u);
from[i]=u,to[i]=v;
}
for(int i=1;i<=n;i++){
if(!dfn[i])
Tarjan(i,i);
}
for(int i=1;i<=dcc_cnt;i++){
if(!vis[i])
Dfs(i,0);
}
/*for(int i=1;i<=dcc_cnt;i++){
int u=G[i].size();
for(int j=0;j<u;j++){
printf("%d %d\n",i,G[i][j]);
}
}*/
int q;
scanf("%d",&q);
//printf("%d %d %d\n",Lca(2,3),dep[2],dep[3]);
for(int i=1;i<=q;i++){
scanf("%d%d",&u,&v);
int a1=from[u],a2=to[u],b1=from[v],b2=to[v];
//printf("%d %d %d %d %d %d %d %d %d\n",a1,dep[a1],a2,dep[a2],b1,dep[b1],b2,dep[b2],Lca(b1,b2));
int a=solve(a1,b1),b=solve(a1,b2),c=solve(a2,b1),d=solve(a2,b2);//四个点都试一下
//printf("%d %d %d %d\n",a,b,c,d);
//printf("%d %d %d\n",a2,b1,Lca(a2,b1));
printf("%d\n",max(max(a,b),max(c,d)));
}
}
}
UVA1464 Traffic Real Time Query System的更多相关文章
- CH#24C 逃不掉的路 和 HDU3686 Traffic Real Time Query System
逃不掉的路 CH Round #24 - 三体杯 Round #1 题目描述 现代社会,路是必不可少的.任意两个城镇都有路相连,而且往往不止一条.但有些路连年被各种XXOO,走着很不爽.按理说条条大路 ...
- 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 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, ...
- HDU Traffic Real Time Query System
题目大意是:对于(n, m)的图,给定边a, b查询从a到b要经过的割点的最少数目. 先tarjan算法求双连通然后缩点,即对于每个割点将周围的每个双连通看成一个点与之相连.然后求解LCA即可,距离d ...
- UVALive-4839 HDU-3686 Traffic Real Time Query System 题解
题目大意: 有一张无向连通图,问从一条边走到另一条边必定要经过的点有几个. 思路: 先用tarjan将双连通分量都并起来,剩下的再将割点独立出来,建成一棵树,之后记录每个点到根有几个割点,再用RMQ求 ...
- 【HDOJ】3686 Traffic Real Time Query System
这题做了几个小时,基本思路肯定是求两点路径中的割点数目,思路是tarjan缩点,然后以割点和连通块作为新节点见图.转化为lca求解.结合点——双连通分量与LCA. /* 3686 */ #includ ...
- hdu 3686 Traffic Real Time Query System 点双两通分量 + LCA。这题有重边!!!
http://acm.hdu.edu.cn/showproblem.php?pid=3686 我要把这题记录下来. 一直wa. 自己生成数据都是AC的.现在还是wa.留坑. 我感觉我现在倒下去床上就能 ...
随机推荐
- Java实现第八届蓝桥杯日期问题
日期问题 题目描述 小明正在整理一批历史文献.这些历史文献中出现了很多日期.小明知道这些日期都在1960年1月1日至2059年12月31日.令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/ ...
- public、potected 、private继承下的子类对父类成员的访问情况
#include<iostream> #include<string> using namespace std; class parent{ protected: int m_ ...
- JVM 之 Linux定位CPU过高问题及优化
项目部署以后出行卡顿现象,所以对问题进行了排查,记录一下排查过程 (从CSDN编辑器贴过来的,图有水印) 1.找进程 top 可以发现,是Java进程导致的CPU过高,致使系统卡顿 2.找线程 ps ...
- 解决Mac上打开txt文件乱码问题
出处:https://www.jianshu.com/p/f55ddf1e9839 经常会在Mac上打开一个txt文件,发现里面的中文都是乱码,问题是在Windows和手机上看都完全是正常的,这就十分 ...
- 使用Vim写LaTeX代码(Vim+Vimtex+Skim)
最近在写博客的时候发现对数学公式的支持并不好,于是就想寻找一个解决方案.我本身是一个爱折腾的人,有时尽管有现成的解决方案我有事也不愿意去用.于是多方查找资料,想寻求一个自定义的解决方案,最终把自己的目 ...
- 10 种常用 Matplotlib 图的 Python 代码
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 喜欢的朋友欢迎关注小编,除了分享技术文章之外还有很多福利,私信“资料”可以 ...
- 国外的教授都说,用这个方式21天就能学会python,这是中国速度
你尝试过吗?按照这个方式,用21天就能学会python编程. 在今年的疫情期间,在家的时间何止21天,有这样一位做财务的朋友,为了提高自己的数据分析能力,在家通过这个方式,跟着21天的规划,坚 ...
- 微信小程序-工具的下载与安装
QQ讨论群:785071190 安装开发工具 前往 开发者工具下载页面 ,根据自己的操作系统下载对应的安装包进行安装,有关开发者工具更详细的介绍可以查看 <开发者工具介绍> .工具安装非常 ...
- mybatis视频教程2-动态参数
/MyBatis_04_DynamicSQL/src/com/atguigu/mybatis/dao/EmployeeMapperDynamicSQL.java package com.atguigu ...
- Haproxy/LVS负载均衡实现+keepalived实现高可用
haproxy+keepalived 集群高可用集群转发 环境介绍 #内核版本 Ubuntu 18.04.4 LTS \n \l 107-Ubuntu SMP Thu Jun 4 11:27:52 U ...