[BZOJ2125]最短路(圆方树DP)

题意:仙人掌图最短路。

算法:圆方树DP,$O(n\log n+Q\log n)$

首先建出仙人掌圆方树(与点双圆方树的区别在于直接连割边,也就是存在圆圆边),然后考虑点u-v的最短路径,显然就是:在圆方树上u-v的路径上的所有边权之和,加上每个环(方点)中连出去的两个点的最短距离。

现在问题就是:如何求出环上两个点的最短路径。考虑这样设定边权,首先显然圆圆边的边权就是原图的边权,然后设一个环在搜索树中深度最小的点为这个环的根,则方圆边的边权是环的根到这个点的最短距离,这个可以在Tarjan的时候直接求出。

但是圆方树问题通常需要在LCA处分圆方点讨论。首先如果LCA是圆点,那么直接做即可。如果是方点,就需要决定要不要走环的另一侧,这个同样直接讨论即可。

具体见代码,感觉思路还是比较清晰的。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define rep(i,l,r) for (int i=l; i<=r; i++)
 4 using namespace std;
 5 
 6 const int N=20010;
 7 int n,m,Q,u,v,w,tot,tim,top,dep[N],len[N],type[N],stk[N];
 8 int dfn[N],low[N],dis[N],lst[N],fa[N][16],sm[N][16];
 9 
10 struct E{
11     int cnt,h[N],to[N<<1],nxt[N<<1],val[N<<1];
12     void add(int u,int v,int w){ to[++cnt]=v; val[cnt]=w; nxt[cnt]=h[u]; h[u]=cnt; }
13 }G,G1;
14 
15 void work(int x,int k){
16     tot++; int t; len[tot]=dis[stk[top]]-dis[x]+lst[stk[top]];
17     do{
18         t=stk[top--];
19         int A=dis[t]-dis[x],B=len[tot]-A;
20         G1.add(tot,t,min(A,B)); type[t]=(A<=B);
21     }while (t!=k);
22     G1.add(x,tot,0);
23 }
24 
25 void Tarjan(int x,int pre){
26     //printf("%d\n",x);
27     dfn[x]=low[x]=++tim; stk[++top]=x;
28     for (int i=G.h[x],k; i; i=G.nxt[i]){
29         if ((k=G.to[i])==pre) continue;
30         if (!dfn[k]){
31             dis[k]=dis[x]+G.val[i]; Tarjan(k,x);
32             //printf("%d %d %d %d\n",x,k,dfn[x],low[k]);
33             if (low[k]>dfn[x]) top--,G1.add(x,k,G.val[i]);
34             else if (low[k]==dfn[x]) work(x,k);
35             low[x]=min(low[x],low[k]);
36         }else low[x]=min(low[x],dfn[k]),lst[x]=G.val[i];
37     }
38 }
39 
40 void dfs(int x,int pre){
41     for (int i=G1.h[x],k; i; i=G1.nxt[i])
42         fa[k=G1.to[i]][0]=x,dep[k]=dep[x]+1,sm[k][0]=G1.val[i],dfs(k,x);
43 }
44 
45 int lca(int u,int v){
46     if (dep[u]<dep[v]) swap(u,v);
47     int t=dep[u]-dep[v],res=0;
48     for (int i=15; ~i; i--) if (t&(1<<i)) res+=sm[u][i],u=fa[u][i];
49     if (u==v) return res;
50     for (int i=15; ~i; i--) if (fa[u][i]!=fa[v][i])
51         res+=sm[u][i]+sm[v][i],u=fa[u][i],v=fa[v][i];
52     if (fa[u][0]<=n) return sm[u][0]+sm[v][0]+res;
53     int A=sm[u][0],B=sm[v][0],mn;
54     if (type[u]==type[v]) mn=min(abs(A-B),len[fa[u][0]]-abs(A-B));
55         else mn=min(A+B,len[fa[u][0]]-A-B);
56     return res+mn;
57 }
58 
59 int main(){
60     freopen("bzoj2125.in","r",stdin);
61     freopen("bzoj2125.out","w",stdout);
62     scanf("%d%d%d",&n,&m,&Q); tot=n;
63     rep(i,1,m) scanf("%d%d%d",&u,&v,&w),G.add(u,v,w),G.add(v,u,w);
64     Tarjan(1,0); dfs(1,0);
65     //rep(i,1,tot) printf("%d ",low[i]); puts("");
66     rep(j,1,15) rep(i,1,tot)
67         fa[i][j]=fa[fa[i][j-1]][j-1],sm[i][j]=sm[i][j-1]+sm[fa[i][j-1]][j-1];
68     rep(i,1,Q) scanf("%d%d",&u,&v),printf("%d\n",lca(u,v));
69     return 0;
70 }

 

转载于:https://www.cnblogs.com/HocRiser/p/9143979.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/251628.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20162317 2017-2018-1 《程序设计与数据结构》第8周学习总结

20162317 2017-2018-1 《程序设计与数据结构》第8周学习总结 教材学习内容总结 1、二叉查找树的定义、性质2、向二叉查找树中添加元素的方法3、在二叉查找树中删除元素的方法4、旋转的定义、方法、意义 教材学习中的问题和解决过程问题1&#xff1a;我在17章中看到这么一句话&a…

ES6模块的转码

浏览器目前还不支持ES6模块,为了实现立刻使用,我们可以将其转为ES5的写法.除了Babel可以用来转码,还有以下两个方法也可以用来转码: ES6 moudule transpilerSystemJS ES6 moudule transpiler是square公司开源的一个转码器,可以将ES6模块转为CommonJS模块或AMD模块,从而在浏览器…

Java基础学习总结(22)——异常处理

2019独角兽企业重金招聘Python工程师标准>>> 一、异常的概念 异常指的是运行期出现的错误&#xff0c;也就是当程序开始执行以后执行期出现的错误。出现错误时观察错误的名字和行号最为重要。 1 package cn.javastudy.summary;2 3 public class TestEx{4 5 …

XAML中格式化日期

要求被格式化数据的类型是DateTime StringFormatyyyy-MM-dd StringFormat{}{0:yyyy-MM-dd}转载于:https://www.cnblogs.com/changbaishan/p/9144584.html

130242014045 林承晖 第2次实验

软件体系结构的第二次实验&#xff08;解释器风格与管道过滤器风格&#xff09; 一、实验目的 1&#xff0e;熟悉体系结构的风格的概念 2&#xff0e;理解和应用管道过滤器型的风格。 3、理解解释器的原理 4、理解编译器模型 二、实验环境 硬件&#xff1a; 软件&#xff1a;P…

AnularJS1事件

在Web应用的组件是松耦合的情况下&#xff0c;比如需要用户验证然后处理授权&#xff0c;即时的通信不总是可行的&#xff0c;因为组件没有耦合在一起。 例如&#xff0c;如果后端对一个请求返回了状态码401&#xff08;表明一个未经授权的请求&#xff09;&#xff0c;我们期望…

Java基础学习总结(8)——super关键字

2019独角兽企业重金招聘Python工程师标准>>> 一、super关键字 在JAVA类中使用super来引用父类的成分&#xff0c;用this来引用当前对象&#xff0c;如果一个类从另外一个类继承&#xff0c;我们new这个子类的实例对象的时候&#xff0c;这个子类对象里面会有一个父类…

conda镜像

转自https://blog.csdn.net/guilutian0541/article/details/81004769 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main conda config --set show…

Java基础学习总结(17)——线程

2019独角兽企业重金招聘Python工程师标准>>> 一、线程的基本概念 线程理解&#xff1a;线程是一个程序里面不同的执行路径 每一个分支都叫做一个线程&#xff0c;main()叫做主分支&#xff0c;也叫主线程。 程只是一个静态的概念&#xff0c;机器上的一个.class文件…

(转)MySQL自带的性能压力测试工具mysqlslap详解

mysqlslap 是 Mysql 自带的压力测试工具&#xff0c;可以模拟出大量客户端同时操作数据库的情况&#xff0c;通过结果信息来了解数据库的性能状况 mysqlslap 的一个主要工作场景就是对数据库服务器做基准测试 例如我们拿到了一台服务器&#xff0c;准备做为数据库服务器&#x…

node.js HelloWord

创建 server.js var http require("http"); http.createServer(function(req,res){ //设置请求头的编码格式 res.writeHead(200,{Content-Type:text/html;charsetutf-8}); //设置网页的编码格式&#xff08;防止中文乱码&#xff09; res.write("<head>&…

JavaScript --- this

介绍: this:引用环境执行的环境对象arguments:一个类数组对象,它包含传入函数的所以参数callee:arguments对象的一个属性,该属性是一个指针,指向拥有arguments对象的函数caller:保存着调用当前函数的函数引用apply()方法:第一个参数是作用域&#xff0c;第二个参数是Array实例…

LeetCode Subarray Sum Equals K

原题链接在这里&#xff1a;https://leetcode.com/problems/subarray-sum-equals-k/description/ 题目&#xff1a; Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k. Example 1: Input:nums …

水木告白工作室:Java从零入门之模仿头条资讯(一)

总体设计 一 &#xff1a;Java语言基础 二 &#xff1a;Spring入门&#xff0c;模板语法和渲染 三 &#xff1a;数据库交互iBatis集成 四&#xff1a; 用户注册 登陆 管理 五&#xff1a; 资讯发布 图片上传 资讯首页 六&#xff1a; 评论中心 站内信 七&#xff1a; Redis入门…

架构师不可不知的十大可扩展架构

2019独角兽企业重金招聘Python工程师标准>>> 可扩展性正是如今软件设计领域最值得优先考虑的要素。然而&#xff0c;计算机科学家们还无法了解一套单独的架构如何才能扩展至各类应用环境当中。相反&#xff0c;我们在数量繁多的方案中所设计出的可扩展性架构&#x…

Winform开发框架中工作流模块的业务表单开发

在我们开发工作流的时候&#xff0c;往往需要设计到具体业务表单信息的编辑&#xff0c;有些是采用动态编辑的&#xff0c;有些则是在开发过程中处理的&#xff0c;各有各的优点&#xff0c;动态编辑的则方便维护各种各样的表单&#xff0c;但是数据的绑定及处理则比较麻烦&…

JavaScript --- 跨浏览器的事件处理程序

var EventUtil {addHandler: function(element, type, handler) { // 添加事件处理程序if (element.addEventListener) { // DOM2级事件处理程序element.addEventListener (type, handler, false) ;} else if (element.attachEvent) { // IE事件处理程序element.attachEve…

RabbitMQ学习总结(2)——安装、配置与监控

2019独角兽企业重金招聘Python工程师标准>>> 一、安装 1、安装Erlang 1&#xff09;系统编译环境&#xff08;这里采用linux/unix 环境&#xff09; ① 安装环境 虚拟机&#xff1a;VMware Workstation 10.0.1 build Linux系统&#xff1a;CentOS6.5 rabbitMQ官网下…

nginx针对某个url限制ip访问,常用于后台访问限制

nginx针对某个url限制ip访问&#xff0c;常用于后台访问限制 假如我的站点后台地址为&#xff1a; http://www.abc.net/admin.php 那么我想限制只有个别ip可以访问后台&#xff0c;那么需要在配置文件中增加&#xff1a;location ~ .*admin.* {allow 1.1.1.1;allow 12.12.12.0/…

JavaScript --- 跨浏览器的事件对象

var EventUtil{addHandler: function(element, type, handler){ // 添加事件方法if (element.addEventListener){element.addEventListener(type, handler, false); // 添加监听事件,第3个参数false代表:冒泡阶段} else if (element.attachEvent) {element.attachEvent("…