bzoj3047:Freda的传呼机&&bzoj2125: 最短路
完结撒花!!!!!!!!!!!
最后一题填坑1A仙人掌WWWWWWW我真流弊
首先把环拆开,环中每一个点连向环的根,然后搞LCA,答案就是套路的d[x]+d[y]-d[lca]*2
然后就可以发现,其实只有当fx和fy在同一个环里面,才有可能通过不同的路线导致答案更小,特判之即可。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std; struct node
{
int x,y,d,next;
}a[],e[];int len,last[],elen,elast[];
void ins(int x,int y,int d)
{
len++;
a[len].x=x;a[len].y=y;a[len].d=d;
a[len].next=last[x];last[x]=len;
}
void eins(int x,int y,int d)
{
elen++;
e[elen].x=x;e[elen].y=y;e[elen].d=d;
e[elen].next=elast[x];elast[x]=elen;
} bool edg[];int cnt,bel[],sum[],ts[];
int fa[],dep[],dis[];
int tp,id[],sdis[];
void DP(int rt,int bac)
{
tp=dep[bac]-dep[rt]+;
for(int i=;i<=tp;i++) id[tp-i+]=bac, bac=fa[bac]; sdis[]=;
for(int i=;i<=tp;i++)
{
sdis[i]=sdis[i-]+dis[id[i]];
ts[id[i]]=sdis[i];
}
cnt++;sum[cnt]=sdis[tp]+dis[rt]; for(int i=;i<=tp;i++)
{
ins(rt,id[i],min(sdis[i],sum[cnt]-sdis[i]));
edg[id[i]]=true;
bel[id[i]]=cnt;
}
}
int z,dfn[],low[];
void cactus(int x)
{
dfn[x]=low[x]=++z;
for(int k=elast[x];k;k=e[k].next)
{
int y=e[k].y;
if(dfn[y]==)
{
fa[y]=x;
dep[y]=dep[x]+;
dis[y]=e[k].d;
cactus(y);
low[x]=min(low[x],low[y]);
}
else if(y!=fa[x])
low[x]=min(low[x],dfn[y]);
} for(int k=elast[x];k;k=e[k].next)
{
int y=e[k].y;
if(fa[y]!=x&&dfn[x]<dfn[y])
{
int t=dis[x];
dis[x]=e[k].d;
DP(x,y);
dis[x]=t;
}
}
} //----------------------------------------- int Bin[];
int f[][];
void dfs(int x)
{
for(int i=;dep[x]>=Bin[i];i++)f[i][x]=f[i-][f[i-][x]]; for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(y!=f[][x])
{
f[][y]=x;
dep[y]=dep[x]+;
dis[y]=dis[x]+a[k].d;
dfs(y);
}
}
}
int LCA(int x,int y,int &fx,int &fy)
{
int w=-;
if(dep[x]<dep[y]){swap(x,y);w=;}
for(int i=;i>=;i--)
if(dep[x]-dep[y]>=Bin[i])x=f[i][x];
if(x==y){fx=-;return x;}
for(int i=;i>=;i--)
if(dep[x]>=Bin[i]&&f[i][x]!=f[i][y])x=f[i][x],y=f[i][y];
if(w==-)fx=x,fy=y;
else fx=y,fy=x;
return f[][x];
} //--------------get_LCA---------------------------- int main()
{
int n,m,Q,x,y,dd;
scanf("%d%d%d",&n,&m,&Q);
len=;memset(last,,sizeof(last));
elen=;memset(elast,,sizeof(elast));
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&dd);
eins(x,y,dd);eins(y,x,dd);
}
z=cnt=;
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(edg,false,sizeof(edg));
fa[]=,dep[]=,cactus();
for(int i=;i<=n;i++)
if(edg[i]==false)
ins(fa[i],i,dis[i]); Bin[]=;for(int i=;i<=;i++)Bin[i]=Bin[i-]*;
f[][]=;dep[]=;dis[]=;dfs(); while(Q--)
{
scanf("%d%d",&x,&y);
int fx,fy,lca=LCA(x,y,fx,fy);
if(fx!=-&&bel[fx]!=&&bel[fx]==bel[fy])
{
dd=abs(ts[fx]-ts[fy]);
printf("%d\n",dis[x]-dis[fx]+dis[y]-dis[fy]+min(dd,sum[bel[fx]]-dd));
}
else
printf("%d\n",dis[x]+dis[y]-*dis[lca]);
}
return ;
}
bzoj3047:Freda的传呼机&&bzoj2125: 最短路的更多相关文章
- bzoj3047: Freda的传呼机 && 2125: 最短路
Description 为了随时与rainbow快速交流,Freda制造了两部传呼机.Freda和rainbow所在的地方有N座房屋.M条双向光缆.每条光缆连接两座房屋,传呼机发出的信号只能沿着光缆传 ...
- [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\) 为方点,则需要额外判断是走环的哪一侧(此时与两个点在环上的相对位置有关.) ...
随机推荐
- animation仿进度条
animation:使用的好可以有很多酷炫效果 仿进度条效果.
- ASP.net参数传递总结
同一页面.aspx与.aspx.cs之间参数传递 1. .aspx.cs接收.aspx的参数:由于.aspx和.aspx.cs为继承关系,所以.aspx.cs可以直接对.aspx中的ID进行值提取,具 ...
- Ubuntu用户自定义脚本开机启动
如果想让自己写的脚本随开机自动执行,可以这样做: 编辑文件/etc/init.d/rc.local,在最后添加用户自定义脚本的完整路径即可. 很简单有木有!!
- unzip 命令巧用举例
1.把文件解压到当前目录下 unzip master.zip 2.如果要把文件解压到指定的目录下,需要用到-d参数. unzip -d /tmp master.zip 3.解压的时候,有时候不想覆盖已 ...
- js移动端 可移动滑块
document.addEventListener('DOMContentLoaded', function() { //动态创建回到首页dom var backDom = document.crea ...
- selenium之浏览器驱动
selenium需要配合浏览器的驱动使用,几个主要的浏览器驱动如下 浏览器 链接 Chrome https://sites.google.com/a/chromium.org/chromedriver ...
- discuz 微社区开通
检测api: http://wsq.discuz.com/?a=apitest
- 腾讯云,搭建nginx静态网站服务器
搭建Http静态服务器环境 任务时间:15min ~ 30min 搭建静态网站,首先需要部署环境.下面的步骤,将告诉大家如何在服务器上通过 Nginx 部署 HTTP 静态服务. 安装 Nginx 在 ...
- 洛谷 2387 NOI2014魔法森林 LCT
[题解] 我们先把边按照$a$值从小到大排序,并按照这个顺序加边. 如果当前要加入的边连接的两点$u$与$v$已经是连通的,那么直接加入这条边就会出现环.这时我们需要删除这个环中$b$值最大的边.因此 ...
- ZooKeeper学习总结(2)——ZooKeeper开源Java客户端ZkClient使用
zkclient是zookeeper的Java客户端.它让Zookeeper API 使用起来更简单:它非常方便订阅各种事件并自动重新绑定事件(会话建立.节点修改.节点删除.子节点变更等):它提供了s ...