LINK:最短路

一张仙人掌图 求图中两点最短路。

\(n<=10000,Q<=10000,w>=1\)

考虑边数是多少 m>=n-1 对于一张仙人掌图 考虑先构建出来dfs树 非树边会形成环 环不可能相交 也没有自环 那么说一每形成一个环需要一条树边和非树边。

所以m<=2n-2.

求图中两点最短路。离线做也不太好做。考虑一下一个点到另外一个点 会经过一些割点 必经之点 那么任意两个割点之间的最短路有两条。

显然其中一条永远没用 考虑构建出圆方树 边权dfs的时候处理一下即可。求距离树上求LCA即可。

不知道哪里挂了 回来再调。

4.6 update:闲来无事拍了一下 发现了自己的思想漏洞。

之前少处理了一种情况 考虑一个环内 两点各自的儿子之间的最短距离。

他们的LCA为方点 这说明了要爬到这个环内然后然后 对于环有两条路径 所以需要特判 我之前只注意到环内点了 所以挂了。

正确的是 判LCA 然后x向上跳 y向上跳 然后计算距离即可。

计算环的距离时我暴力了一点 求了一发 L 和 R数组.

const int MAXN=20010;
int n,m,Q,len=1,cnt,top,sum,len1,id,cc;
int dfn[MAXN],low[MAXN],s[MAXN],f[MAXN][20],a[MAXN],b[MAXN],Log[MAXN],L[MAXN],R[MAXN];
int lin[MAXN],ver[MAXN<<1],nex[MAXN<<1],e[MAXN<<1],d[MAXN],dis[MAXN],w[MAXN],h[MAXN];
int lin1[MAXN],ver1[MAXN<<1],nex1[MAXN<<1],e1[MAXN<<1];
inline void add(int x,int y,int z){ver[++len]=y;nex[len]=lin[x];lin[x]=len;e[len]=z;}
inline void add1(int x,int y,int z){ver1[++len1]=y;nex1[len1]=lin1[x];lin1[x]=len1;e1[len1]=z;}
inline void solve(int x)
{
add1(x,id,0);
rep(2,sum,i)
{
L[a[i]]=dis[a[i]]-dis[a[1]];R[a[i]]=b[a[i]]-dis[a[1]];
if(i+1<=sum)
{
b[a[i+1]]=dis[a[i]]-dis[a[i+1]]+b[a[i]];
//if(dis[a[i]]<=dis[a[i+1]])cout<<"ww"<<endl;
}
w[a[i]]=min(dis[a[i]],b[a[i]]);
}
rep(2,sum,i)add1(id,a[i],w[a[i]]-dis[a[1]]);
}
inline void dfs(int x)
{
dfn[x]=low[x]=++cnt;
s[++top]=x;
go(x)
{
if(!dfn[tn])
{
dis[tn]=dis[x]+e[i];
h[tn]=i;dfs(tn);
low[x]=min(low[x],low[tn]);
if(low[tn]>=dfn[x])
{
int y=0;sum=0;
a[++sum]=x;
while(y!=tn)
{
y=s[top--];
a[++sum]=y;
}
++id;solve(x);
}
}
else
{
low[x]=min(low[x],dfn[tn]);
if((i^1)!=h[x])b[x]=dis[tn]+e[i];
}
}
}
inline void dfs(int x,int fa)
{
d[x]=d[fa]+1;f[x][0]=fa;
rep(1,Log[d[x]],i)f[x][i]=f[f[x][i-1]][i-1];
for(int i=lin1[x];i;i=nex1[i])
{
int tn=ver1[i];
dis[tn]=dis[x]+e1[i];
dfs(tn,x);
}
}
inline int LCA(int x,int y)
{
if(d[x]<d[y])swap(x,y);
fep(Log[d[x]],0,i)
if(d[f[x][i]]>=d[y])x=f[x][i];
if(x==y)return x;
fep(Log[d[x]],0,i)
if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
return f[x][0];
}
inline int get_x(int x,int w)
{
fep(Log[d[x]],0,i)if(d[f[x][i]]>=w)x=f[x][i];
return x;
}
int main()
{
freopen("1.in","r",stdin);
get(n);get(m);get(Q);
rep(1,m,i)
{
int x,y,z;
get(x);get(y);get(z);
add(x,y,z);add(y,x,z);
b[i]=INF;
}
id=n;dfs(1);
rep(2,id,i)Log[i]=Log[i>>1]+1;
dfs(1,0);
rep(1,Q,i)
{
int get(x);int get(y);
int lca=LCA(x,y);
if(lca>n)
{
int xx=get_x(x,d[lca]+1);
int yy=get_x(y,d[lca]+1);
if(L[xx]<L[yy])swap(xx,yy);
int ww=min(L[xx]-L[yy],R[xx]+L[yy]);
put(ww+dis[x]-dis[xx]+dis[y]-dis[yy]);continue;
}
put(dis[x]+dis[y]-dis[lca]*2);
}
return 0;
}

bzoj 2125 最短路 点双 圆方树的更多相关文章

  1. UOJ#23. 【UR #1】跳蚤国王下江南 仙人掌 Tarjan 点双 圆方树 点分治 多项式 FFT

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ23.html 题目传送门 - UOJ#23 题意 给定一个有 n 个节点的仙人掌(可能有重边). 对于所有 ...

  2. 【BZOJ】2125: 最短路 圆方树(静态仙人掌)

    [题意]给定带边权仙人掌图,Q次询问两点间最短距离.n,m,Q<=10000 [算法]圆方树处理仙人掌问题 [题解]树上的两点间最短路问题,常用倍增求LCA解决,考虑扩展到仙人掌图. 先对仙人掌 ...

  3. BZOJ.2125.最短路(仙人掌 圆方树)

    题目链接 圆方树.做题思路不写了.. 就是当LCA是方点时跳进那个环可以分类讨论一下用树剖而不必须用倍增: 如果v是u的(唯一的那个)重儿子,那么u的DFS序上+1的点即是要找的:否则v会引出一条新的 ...

  4. BZOJ 压力 tarjan 点双联通分量+树上差分+圆方树

    题意 如今,路由器和交换机构建起了互联网的骨架.处在互联网的骨干位置的核心路由器典型的要处理100Gbit/s的网络流量. 他们每天都生活在巨大的压力之下.小强建立了一个模型.这世界上有N个网络设备, ...

  5. 【BZOJ2125】最短路(仙人掌,圆方树)

    [BZOJ2125]最短路(仙人掌,圆方树) 题面 BZOJ 求仙人掌上两点间的最短路 题解 终于要构建圆方树啦 首先构建出圆方树,因为是仙人掌,和一般图可以稍微的不一样 直接\(tarjan\)缩点 ...

  6. 【刷题】BZOJ 2125 最短路

    Description 给一个N个点M条边的连通无向图,满足每条边最多属于一个环,有Q组询问,每次询问两点之间的最短路径. Input 输入的第一行包含三个整数,分别表示N和M和Q 下接M行,每行三个 ...

  7. BZOJ2125 最短路 圆方树、倍增

    传送门 对仙人掌建立圆方树,然后对边定权 对于圆点和圆点之间的边,是原来仙人掌上的桥,边权保持不变 对于圆点和方点之间的边,将圆方树看做以一个圆点为根的有根树之后,一个方点的父亲一定是一个圆点.对于这 ...

  8. BZOJ.2125.最短路(仙人掌 最短路Dijkstra)

    题目链接 多次询问求仙人掌上两点间的最短路径. 如果是在树上,那么求LCA就可以了. 先做着,看看能不能把它弄成树. 把仙人掌看作一个图(实际上就是),求一遍根节点到每个点的最短路dis[i]. 对于 ...

  9. 2018.07.25 bzoj2125: 最短路(圆方树+倍增)

    传送门 人生的第一道仙人掌. 这道题求是仙人掌上的最短路. 先建出圆方树,然后用倍增跑最短路,当lca" role="presentation" style=" ...

随机推荐

  1. django中的懒加载机制

    懒加载在前端中的意义: 懒加载的主要目的就是作为服务器前端的优化,减少请求次数或者延迟请求数. 实现原理: 先加载一部分数据,当触发某个条件时利用异步加载剩余的数据,新得到的数据不会影响原有数据的显示 ...

  2. 小程序checkbox-group只获取到一个值

    wx:for循环不能写在checkbox-group标签上 wx:for循环不能写在checkbox-group标签上 wx:for循环不能写在checkbox-group标签上 wx:for循环不能 ...

  3. jira仪表盘的建立与共享

    一般在项目测试阶段,可以通过jira仪表盘清晰的展示bug的各个状态的数量,各个开发人员的bug数量. 有效督促开发解决问题. 也为测试日报提供了良好的数据支持,减少人工统计的工作量. 1.建议筛选器 ...

  4. Java入门基础学习,成为一个Java程序员的必备知识

    引言 众所周知,Java是一种面向对象的编程语言.您可以在Windows操作系统上编写Java源代码,而在Linux操作系统上运行编译后的字节码,而无需修改源代码. 数据类型 Java 有 2 种数据 ...

  5. Kafka入门(1):概述

    摘要 在本文中,我将从为什么需要消息队列开始讲起,举两个小例子,跟你聊聊目前消息队列的一些使用场景. 比如消息队列在复杂系统中的解耦,又比如消息队列在高并发下的场景如果让流量变得更平缓. 随后我会跟你 ...

  6. node+express实现简单的增删改查

    var express = require('express'); var bodyParser = require("body-parser"); var cors = requ ...

  7. python面试题:redis数据库

    来源链接: https://www.cnblogs.com/jasontec/p/9699242.html https://www.cnblogs.com/Java3y/p/10266306.html ...

  8. python 并发专题(十):基础部分补充(二)线程

    什么是线程 标准描述开启一个进程:开启一个进程:进程会在内存中开辟一个进程空间,将主进程的资料数据全部复制一份,线程会执行里面的代码. ***进程是资源单位, 线程是执行单位:是操作系统调度的最小单元 ...

  9. JavaScript之setinterval的具体使用

    关于setInterval在api文档中也有很详细的解释,比如下面那两个: setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式. setInterval() 方法会不停 ...

  10. 网易实战分享|云信IM SDK接口设计实践

    引语 IM (Instant Messaging)是网络上最流行的通信方式,与日常生活息息相关.IM软件也层出不穷,例如:微信.QQ.易信等.通过多年深耕和技术沉淀,云信产出了一套成熟稳定的IM SD ...