【JZOJ1914】【BZOJ2125】最短路
description
给一个N个点M条边的连通无向图,满足每条边最多属于一个环,有Q组询问,每次询问两点之间的最短路径。
analysis
建出圆方树后,可以知道仙人掌上每一个方点连着的边双其实就是一个简单环
\(tarjan\)缩环的时候可以先弄出每个环的边权和并做一个前缀和,这样环中两点距离就可求
设\(dis[i]\)表示从根节点到\(i\)节点的最小值,若\(x,y\)两点\(LCA\)是原点,则可以直接求
若为方点则表示\(x,y\)距离\(LCA\)最近的祖先是环上不相邻两点,只需要再判断环上这两点最短距离即可
code
#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<map>
#define MAXN 100005
#define MAXM 200005
#define ll long long
#define reg register ll
#define max(x,y) ((x>y)?(x):(y))
#define min(x,y) ((x<y)?(x):(y))
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)
#define rep(i,a) for (reg i=las[a];i;i=nex[i])
using namespace std;
ll anc[MAXN][16];
ll las[MAXM],nex[MAXM],tov[MAXM],len[MAXM];
ll dfn[MAXN],low[MAXN],stack[MAXN];
ll fa[MAXN],sum[MAXN],dep[MAXN],dis[MAXN],size[MAXN];
ll n,m,q,nn,tot,tot1,num,top;
map<ll,ll>mp[MAXN],c[MAXN];
vector<ll>v[MAXN];
inline ll read()
{
ll x=0,f=1;char ch=getchar();
while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline void link(ll x,ll y,ll z){nex[++tot]=las[x],las[x]=tot,tov[tot]=y,len[tot]=z;}
inline void tarjan(ll x)
{
dfn[x]=low[x]=++tot,stack[++top]=x;
rep(i,x)if (!dfn[tov[i]])
{
tarjan(tov[i]),low[x]=min(low[x],low[tov[i]]);
if (low[tov[i]]>=dfn[x])
{
ll tmp=0,last=0;++n;
while (tmp!=tov[i])
{
last=tmp,tmp=stack[top--];
v[n].push_back(tmp),v[tmp].push_back(n);
size[n]+=last==0?mp[tmp][x]:mp[tmp][last];
c[n][tmp]=size[n];
}
v[n].push_back(x),v[x].push_back(n);
size[n]+=mp[x][tmp],c[n][x]=size[n];
}
}
else low[x]=min(low[x],dfn[tov[i]]);
}
inline ll query(ll pos,ll x,ll y)
{
ll tmp=abs(c[pos][x]-c[pos][y]);
return min(tmp,size[pos]-tmp);
}
inline void dfs(ll x,ll y)
{
anc[x][0]=y,dep[x]=dep[y]+1;
fo(i,1,15)anc[x][i]=anc[anc[x][i-1]][i-1];
if (x<=nn)
{
ll ff=anc[y][0];
dis[x]=x==1?0:dis[ff]+query(y,x,ff);
}
fo(i,0,v[x].size()-1)if (v[x][i]!=y)dfs(v[x][i],x);
}
inline ll lca(ll x,ll y)
{
if (dep[x]<dep[y])swap(x,y);
fd(i,15,0)if (dep[anc[x][i]]>=dep[y])x=anc[x][i];
if (x==y)return x;
fd(i,15,0)if (anc[x][i]!=anc[y][i])x=anc[x][i],y=anc[y][i];
return anc[x][0];
}
inline ll get(ll x,ll y,ll z)
{
ll ans=dis[x]+dis[y];
fd(i,15,0)
{
if (dep[anc[x][i]]>dep[z])x=anc[x][i];
if (dep[anc[y][i]]>dep[z])y=anc[y][i];
}
return ans-dis[x]-dis[y]+query(z,x,y);
}
int main()
{
//freopen("T2.in","r",stdin);
//freopen("T2.out","w",stdout);
n=nn=read(),m=read(),q=read();
fo(i,1,m)
{
ll x=read(),y=read(),z=read();
link(x,y,z),link(y,x,z),mp[x][y]=mp[y][x]=z;
}
tarjan(1),dfs(1,0);
while (q--)
{
ll x=read(),y=read(),LCA=lca(x,y);
printf("%lld\n",LCA<=nn?dis[x]+dis[y]-2*dis[LCA]:get(x,y,LCA));
}
return 0;
}
【JZOJ1914】【BZOJ2125】最短路的更多相关文章
- [BZOJ2125]最短路(圆方树DP)
题意:仙人掌图最短路. 算法:圆方树DP,$O(n\log n+Q\log n)$ 首先建出仙人掌圆方树(与点双圆方树的区别在于直接连割边,也就是存在圆圆边),然后考虑点u-v的最短路径,显然就是:在 ...
- bzoj2125 最短路
Description 给一个N个点M条边的连通无向图,满足每条边最多属于一个环,有Q组询问,每次询问两点之间的最短路径. Input 输入的第一行包含三个整数,分别表示N和M和Q 下接M行,每行三个 ...
- BZOJ2125 最短路 圆方树、倍增
传送门 对仙人掌建立圆方树,然后对边定权 对于圆点和圆点之间的边,是原来仙人掌上的桥,边权保持不变 对于圆点和方点之间的边,将圆方树看做以一个圆点为根的有根树之后,一个方点的父亲一定是一个圆点.对于这 ...
- 2018.07.25 bzoj2125: 最短路(圆方树+倍增)
传送门 人生的第一道仙人掌. 这道题求是仙人掌上的最短路. 先建出圆方树,然后用倍增跑最短路,当lca" role="presentation" style=" ...
- BZOJ2125 最短路 【仙人掌最短路】
题目 给一个N个点M条边的连通无向图,满足每条边最多属于一个环,有Q组询问,每次询问两点之间的最短路径. 输入格式 输入的第一行包含三个整数,分别表示N和M和Q 下接M行,每行三个整数v,u,w表示一 ...
- bzoj2125 最短路——仙人掌两点间距离
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2125 仙人掌!模仿 lyd 的代码写的,也算是努力理解了: 主要分成 lca 在环上和不在环 ...
- [BZOJ2125]最短路[圆方树]
题意 给定仙人掌,多次询问两点之间的最短路径. \(n\le 10000, Q\le 10000\) 分析 建出圆方树,分路径 lca 是圆点还是方点讨论. 预处理出根圆点到每个圆点的最短距离 \( ...
- 【题解】Bzoj2125最短路
处理仙人掌 ---> 首先建立出圆方树.则如果询问的两点 \(lca\) 为圆点,直接计算即可, 若 \(lca\) 为方点,则需要额外判断是走环的哪一侧(此时与两个点在环上的相对位置有关.) ...
- bzoj3047:Freda的传呼机&&bzoj2125: 最短路
完结撒花!!!!!!!!!!! 最后一题填坑1A仙人掌WWWWWWW我真流弊 首先把环拆开,环中每一个点连向环的根,然后搞LCA,答案就是套路的d[x]+d[y]-d[lca]*2 然后就可以发现,其 ...
- 图论杂项细节梳理&模板(虚树,圆方树,仙人掌,欧拉路径,还有。。。)
orzYCB 虚树 %自为风月马前卒巨佬% 用于优化一类树形DP问题. 当状态转移只和树中的某些关键点有关的时候,我们把这些点和它们两两之间的LCA弄出来,以点的祖孙关系连成一棵新的树,这就是虚树. ...
随机推荐
- Python--MySql(主键的创建方式、存储引擎、存储过程、索引、pymsql)
主键的创建方式 1. create table stud( id int not null unique, name ) ); mysql> desc stud; +-------+------ ...
- 后端优化(2)—— BA与图优化
- BZOJ 4032: [HEOI2015]最短不公共子串(后缀自动机+记忆化搜索)
传送门 解题思路 首先需要预处理两个串\(nxt(i)(j)\)表示i位置之后最近的\(j\). 第一问直接对\(b\)建后缀自动机,枚举\(a\)的起点暴力匹配. 第二问枚举\(a\)的起点,\(b ...
- JAVA学习之面向对象
面向对象是相对面向过程而言面向过程:强调的是功能行为面向对象:将功能封装进对象,强调具备了功能的对象 不论面向对象还是面向过程都是一种开发思想而已.举一个例子来理解面向对象和面向过程把大象装进冰箱分三 ...
- 深入理解finally关键字,Finally到底是在return前面执行还是在return后面执行
一:2种finally不会执行的情况 a.在try语句之前就return了 b.try语句中有System.exit();语句 二:finally语句在return执行之后,return返回之前执行 ...
- 安装graphviz
环境win10 1. 下载安装包首先进入官网下载msi文件 安装,一路next,不需要注意什么 2.设置环境变量 安装完毕之后,我们需要手动配置环境变量. 找到刚才我们安装地址,进入graphviz, ...
- java 并发——CountDownLatch
java 并发--CountDownLatch 简介 public class CountDownLatch { private final Sync sync; private static fin ...
- vue中按需引入mint-UI报Error: .plugins[3][1] must be an object, false, or undefined
{ "presets": ["@babel/preset-env", "@babel/preset-react"], "plugi ...
- Qt4 QWebView的使用例子
最近项目中使用QT4框架开发PC端软件,所以耐着性子学习了一下QT相关的东西. 下面是QT4中QWebView的使用方法,觉得蛮方便的. 我使用的开发环境是:Win7+Qt 4.8.5开发库+qtcr ...
- java并发锁ReentrantReadWriteLock读写锁源码分析
1.ReentrantReadWriterLock 基础 所谓读写锁,是对访问资源共享锁和排斥锁,一般的重入性语义为如果对资源加了写锁,其他线程无法再获得写锁与读锁,但是持有写锁的线程,可以对资源加读 ...