bzoj 2125 最短路 点双 圆方树
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 最短路 点双 圆方树的更多相关文章
- UOJ#23. 【UR #1】跳蚤国王下江南 仙人掌 Tarjan 点双 圆方树 点分治 多项式 FFT
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ23.html 题目传送门 - UOJ#23 题意 给定一个有 n 个节点的仙人掌(可能有重边). 对于所有 ...
- 【BZOJ】2125: 最短路 圆方树(静态仙人掌)
[题意]给定带边权仙人掌图,Q次询问两点间最短距离.n,m,Q<=10000 [算法]圆方树处理仙人掌问题 [题解]树上的两点间最短路问题,常用倍增求LCA解决,考虑扩展到仙人掌图. 先对仙人掌 ...
- BZOJ.2125.最短路(仙人掌 圆方树)
题目链接 圆方树.做题思路不写了.. 就是当LCA是方点时跳进那个环可以分类讨论一下用树剖而不必须用倍增: 如果v是u的(唯一的那个)重儿子,那么u的DFS序上+1的点即是要找的:否则v会引出一条新的 ...
- BZOJ 压力 tarjan 点双联通分量+树上差分+圆方树
题意 如今,路由器和交换机构建起了互联网的骨架.处在互联网的骨干位置的核心路由器典型的要处理100Gbit/s的网络流量. 他们每天都生活在巨大的压力之下.小强建立了一个模型.这世界上有N个网络设备, ...
- 【BZOJ2125】最短路(仙人掌,圆方树)
[BZOJ2125]最短路(仙人掌,圆方树) 题面 BZOJ 求仙人掌上两点间的最短路 题解 终于要构建圆方树啦 首先构建出圆方树,因为是仙人掌,和一般图可以稍微的不一样 直接\(tarjan\)缩点 ...
- 【刷题】BZOJ 2125 最短路
Description 给一个N个点M条边的连通无向图,满足每条边最多属于一个环,有Q组询问,每次询问两点之间的最短路径. Input 输入的第一行包含三个整数,分别表示N和M和Q 下接M行,每行三个 ...
- BZOJ2125 最短路 圆方树、倍增
传送门 对仙人掌建立圆方树,然后对边定权 对于圆点和圆点之间的边,是原来仙人掌上的桥,边权保持不变 对于圆点和方点之间的边,将圆方树看做以一个圆点为根的有根树之后,一个方点的父亲一定是一个圆点.对于这 ...
- BZOJ.2125.最短路(仙人掌 最短路Dijkstra)
题目链接 多次询问求仙人掌上两点间的最短路径. 如果是在树上,那么求LCA就可以了. 先做着,看看能不能把它弄成树. 把仙人掌看作一个图(实际上就是),求一遍根节点到每个点的最短路dis[i]. 对于 ...
- 2018.07.25 bzoj2125: 最短路(圆方树+倍增)
传送门 人生的第一道仙人掌. 这道题求是仙人掌上的最短路. 先建出圆方树,然后用倍增跑最短路,当lca" role="presentation" style=" ...
随机推荐
- HTML5(六)表单合集
HTML5 表单元素 HTML5 新的表单元素 HTML5 有以下新的表单元素: datalist keygen output HTML5 datalist 元素 <datalist> 元 ...
- 调整数组顺序使奇数位于偶数前面(剑指offer-13)
方法1:新建两个数组,一个数组用来放奇数,一个数组用来放偶数,最后再把它们合并起来. 1 import java.util.*; 2 public class Solution { 3 public ...
- Vue---day05
目录 2. 客户端项目搭建 2.1 创建项目目录 2.2 初始化项目 2.3 安装路由vue-router 2.3.1 下载安装路由组件 2.3.2 配置路由 2.3.2.1 初始化路由对象 2.3. ...
- kubernetes系列(十四) - 存储之PersistentVolume
1. PersistentVolume(PV)简介 1.1 为什么需要Persistent Volume(PV) 1.2 PersistentVolume(PV)和Volume的区别 1.3 PV和P ...
- 机器学习03 /jieba详解
机器学习03 /jieba详解 目录 机器学习03 /jieba详解 1.引言 2.分词 2.1.jieba.cut && jieba.cut_for_search 2.2.jieba ...
- 目录(Python基础)
Python之介绍.基本语法.流程控制 Python之列表.字典.集合 Python之函数.递归.内置函数 Python之迭代器.装饰器.软件开发规范 Python之常用模块学习(一) Python之 ...
- redis(十四):Redis 有序集合(sorted set)
Redis 有序集合(sorted set) Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是通过 ...
- JAVA集合三:几种Set框架
参考链接: HOW2J.CN HashSet简单讲解 HashSet HashSet与C++STL中Set基本类似,具有的特点便是: 集合中元素不可重复 集合中元素顺序 ≠ 插入顺序 常用方法 功能 ...
- Electron-vue 项目搭建
Electron 应用技术体系推荐 目录结构 demo(项目名称) ├─ .electron-vue(webpack配置文件) │ └─ build.js(生产环境构建代码) | └─ dev-cl ...
- day12:闭包函数&匿名函数
闭包函数 闭包函数的定义: 如果内函数使用了外函数的局部变量并且外函数把内函数返回出来的过程 叫做闭包里面的内函数是闭包函数 一个简单的闭包函数示例: def songyunjie_family(): ...