【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弄出来,以点的祖孙关系连成一棵新的树,这就是虚树. ...
随机推荐
- OpenLayers API整理
整理的Openlayers 的知识笔记,随着运用不断加深理解,也会不断更新. 本文链接:Openlayers API整理 作者:狐狸家的鱼 GitHub:八至 一.创建地图 1.地图Map 创建地图底 ...
- mysql 查询表的最大时间 的数据
SELECT * from (SELECT MAX(a.update_date) as q ,a.monitoring_point_id from biz_monitoring_point_recor ...
- 【Linux】 Centos7 安装 mysql-8.0
本文介绍使用rpm包安装mysql, 以 mysql-8.0.17-1.el7.x86_64.rpm-bundle.tar 为例: 1.下载 MySQL下载地址:https://dev.mysql.c ...
- python reduce()函数使用
reduce()的使用方法形如reduce(function, iterable[, initializer]),它的形式和map()函数一样.不过参数f(x)必须有两个参数,initializer是 ...
- 阿里云epel源
epel是个好东西,不过国外的速度实在是不能忍受.所以 有了这篇文章.1. 首先卸载以前装的epel以免影响 rpm -e epel-release 2. 下载阿里提供的epel wget -P /e ...
- Python文章导航
1.Python+Eclipse安装.配置: http://www.cnblogs.com/rhyswang/p/8087752.html 2.数学运算及math库: http://www.cnblo ...
- Java数据类型简介
Java数据类型 以下两行Java代码定义了两个整数:num1和num2: num1和num2是两个int类型的变量. int关键字指定它的后面是变量的名称,并表示数据类型整数,例如:10,15,70 ...
- 厉害了,Spring团队又开源 nohttp 项目!
作者:h4cd 来源:https://www.oschina.net/news/107377/spring-opensource-nohttp Spring 团队开源 nohttp 项目,用以查找.替 ...
- Scrapy框架: 登录网站
一.使用cookies登录网站 import scrapy class LoginSpider(scrapy.Spider): name = 'login' allowed_domains = ['x ...
- 【模板】fread读入优化 & fwrite输出优化
#include <iostream> #include <cstdio> #include <cctype> #define SIZE (1 << 2 ...