题目链接

圆方树。做题思路不写了。。

就是当LCA是方点时跳进那个环可以分类讨论一下用树剖而不必须用倍增:

如果v是u的(唯一的那个)重儿子,那么u的DFS序上+1的点即是要找的;否则v会引出一条新的链。

不用圆方树的做法(代码错了不想改了,但是能A)

//3876kb	148ms(Rank6!)
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 50000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
const int N=10005<<1,M=N<<2;//点数!(方点) int n,m,Q,tot,Index,dfn[N],low[N],fa[N],dis[N],cdis[N],sz[N],son[N],dep[N],top[N],ref[N],cnt;
char IN[MAXIN],*SS=IN,*TT=IN;
struct Edge
{
int Enum,H[N],nxt[M],to[M],val[M];
inline void AddEdge(int u,int v,int w){
to[++Enum]=v, nxt[Enum]=H[u], val[Enum]=w, H[u]=Enum;
to[++Enum]=u, nxt[Enum]=H[v], val[Enum]=w, H[v]=Enum;
}
}g,t; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
void Build(int u,int v,int d)//v->...->u->v
{
for(int i=v; i!=u; i=fa[i]) cdis[i]=d, d+=dis[i];//直接用个dis[]记来时边的权值
cdis[++tot]=d/*length of circle*/, t.AddEdge(tot,u,0);
for(int i=v; i!=u/*fa[u]*/; i=fa[i]) t.AddEdge(tot,i,std::min(cdis[i],d-cdis[i]));
}
void Tarjan(int x)
{
dfn[x]=low[x]=++Index;
for(int v,i=g.H[x]; i; i=g.nxt[i])
if(g.to[i]!=fa[x])
{
if(!dfn[v=g.to[i]])
fa[v]=x, dis[v]=g.val[i], Tarjan(v), low[x]=std::min(low[x],low[v]);
else low[x]=std::min(low[x],dfn[v]);
if(low[v]>dfn[x]) t.AddEdge(x,v,g.val[i]);//Round point
}
for(int v,i=g.H[x]; i; i=g.nxt[i])
if(fa[v=g.to[i]]!=x && dfn[v]>dfn[x]) Build(x,v,g.val[i]);//Square point
}
void DFS1(int x)
{
int mx=0; sz[x]=1;
for(int v,i=t.H[x]; i; i=t.nxt[i])
if((v=t.to[i])!=fa[x])
{
dep[v]=dep[x]+1, dis[v]=dis[x]+t.val[i], fa[v]=x, DFS1(v), sz[x]+=sz[v];
if(sz[v]>mx) mx=sz[v], son[x]=v;
}
}
void DFS2(int x,int tp)
{
top[x]=tp, ref[dfn[x]=++cnt]=x;
if(son[x]){
DFS2(son[x],tp);
for(int i=t.H[x]; i; i=t.nxt[i])
if(t.to[i]!=fa[x]&&t.to[i]!=son[x]) DFS2(t.to[i],t.to[i]);
}
}
int LCA(int u,int v)
{
while(top[u]!=top[v]) dep[top[u]]>dep[top[v]]?u=fa[top[u]]:v=fa[top[v]];
return dep[u]<dep[v]?u:v;
}
int Get_p(int u,int lca)
{
int las=u;
while(top[u]!=top[lca]) u=fa[las=top[u]];
return u==lca?las:ref[dfn[lca]+1];
} int main()
{
tot=n=read(),m=read(),Q=read();
for(int u,v,i=1; i<=m; ++i) u=read(),v=read(),g.AddEdge(u,v,read());
Tarjan(1), dis[1]=fa[1]=0, DFS1(1), DFS2(1,1);
int u,v,w,p1,p2;
while(Q--)
{
u=read(),v=read(),w=LCA(u,v);
if(w<=n) printf("%d\n",dis[u]+dis[v]-(dis[w]<<1));//没有负边,圆上顺序。。无所谓了。
else p1=Get_p(u,w), p2=Get_p(v,w), printf("%d\n",dis[u]-dis[p1]+dis[v]-dis[p2]+std::min(std::abs(cdis[p2]-cdis[p1]),cdis[w]-std::abs(cdis[p2]-cdis[p1])));//这是cdis[p]不是cdis[u/v]!mmpzz错误调了半个多小时
}
return 0;
}

BZOJ.2125.最短路(仙人掌 圆方树)的更多相关文章

  1. 仙人掌&圆方树学习笔记

    仙人掌&圆方树学习笔记 1.仙人掌 圆方树用来干啥? --处理仙人掌的问题. 仙人掌是啥? (图片来自于\(BZOJ1023\)) --也就是任意一条边只会出现在一个环里面. 当然,如果你的图 ...

  2. 仙人掌 && 圆方树 && 虚树 总结

    仙人掌 && 圆方树 && 虚树 总结 Part1 仙人掌 定义 仙人掌是满足以下两个限制的图: 图完全联通. 不存在一条边处在两个环中. 其中第二个限制让仙人掌的题做 ...

  3. 仙人掌&圆方树

    仙人掌&圆方树 Tags:图论 [x] [luogu4320]道路相遇 https://www.luogu.org/problemnew/show/P4320 [ ] [SDOI2018]战略 ...

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

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

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

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

  6. UOJ.87.mx的仙人掌(圆方树 虚树)(未AC)

    题目链接 本代码10分(感觉速度还行..). 建圆方树,预处理一些东西.对询问建虚树. 对于虚树上的圆点直接做:对于方点特判,枚举其所有儿子,如果子节点不在该方点代表的环中,跳到那个点并更新其val, ...

  7. BZOJ.5329.[SDOI2018]战略游戏(圆方树 虚树)

    题目链接 显然先建圆方树,方点权值为0圆点权值为1,两点间的答案就是路径权值和减去起点终点. 对于询问,显然可以建虚树.但是只需要计算两关键点间路径权值,所以不需要建出虚树.统计DFS序相邻的两关键点 ...

  8. bzoj 2125 最短路——仙人掌两点间最短路

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2125 因为看了TJ又抄了标程,现在感觉还是轻飘飘的……必须再做一遍. 两点间的情况: 1.直 ...

  9. 图论杂项细节梳理&模板(虚树,圆方树,仙人掌,欧拉路径,还有。。。)

    orzYCB 虚树 %自为风月马前卒巨佬% 用于优化一类树形DP问题. 当状态转移只和树中的某些关键点有关的时候,我们把这些点和它们两两之间的LCA弄出来,以点的祖孙关系连成一棵新的树,这就是虚树. ...

随机推荐

  1. linux中set、unset、export、env、declare,readonly的区别以及用法

    set命令显示当前shell的变量,包括当前用户的变量;   env命令显示当前用户的变量;   export命令显示当前导出成用户变量的shell变量.           每个shell有自己特有 ...

  2. 利用Volatility对Linux内存取证分析-常用命令翻译

    命令翻译 linux_apihooks - 检查用户名apihooks linux_arp - 打印ARP表 linux_aslr_shift - 自动检测Linux aslr改变 linux_ban ...

  3. PHP 中 int 和 integer 类型的区别

    半夜整理东西,发现一个以前没留意到的小问题. function show($id) : int { return $id; } function show($id) : integer { retur ...

  4. 如何使用vs2012单步调试uGUI(unity3d 5.3f4)

    下载uGUI源代码 uGUI源代码地址:https://bitbucket.org/Unity-Technologies/ui 下载代码工具:tortoisehg-3.6.2-x64.msi http ...

  5. 简单的搭mysql开发环境

    所需软件  环境win8 64bit mysql5.7.16winx64.zip mysql-workbench-community-6.3.5-win32.zip 安装完了之后到mysql/bin下 ...

  6. python面向对象(七)属性方法的添加

    ​ 通常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性.下来我就讲下添加属性和方法,同时也将下限值添加属性方法. 添加属性 ...

  7. C++链接与装载

    1..obj文件的内部结构 2.映射到进程虚拟空间 3.链接的原理    C++ Code  123456789   1.未解决符号表:提供了所有在该编译单元里引用但是定义并不在本编译单元里的符号及其 ...

  8. js交互

    Js和native交互的方法与问题 实现JS和Native交互有两种方式: 第一种:shouldOverrideUrlLoading(WebView view, String url) 通过给WebV ...

  9. 一键复制功能 - Vue

    经常遇到一键复制功能,简单记录一下.这里使用的是clipboard插件:https://clipboardjs.com/ 第一步 安装:npm install clipboard --save 第二步 ...

  10. Hive(五)数据类型与库表操作以及中文乱码

    一.数据类型 1.基本数据类型 Hive 支持关系型数据中大多数基本数据类型 类型 描述 示例 boolean true/false TRUE tinyint 1字节的有符号整数 -128~127 1 ...