仙人掌上的最短路,这里有详细的题解
http://pan.baidu.com/s/1wzCpC
我觉得讲的很清楚,不懂的见代码注释吧

  1 type node=record
  2        po,next,num:longint;
  3      end;
  4
  5 var e,w:array[0..200010] of node;
  6     dfn,low,p,q,mark,s,d,dis,dep,fa:array[0..10010] of longint;
  7     anc:array[0..10010,0..20] of longint;
  8     v:array[0..10010] of boolean;
  9     st:array[0..1000010] of longint;
 10     t,h,i,len,x,y,z,n,m,tot,qq:longint;
 11
 12 function min(a,b:longint):longint;
 13   begin
 14     if a>b then exit(b) else exit(a);
 15   end;
 16
 17 procedure add(x,y,z:longint);
 18   begin
 19     inc(len);
 20     e[len].po:=y;
 21     e[len].next:=p[x];
 22     e[len].num:=z;
 23     p[x]:=len;
 24   end;
 25
 26 procedure fadd(x,y:longint);
 27   begin
 28     inc(len);
 29     w[len].po:=y;
 30     w[len].next:=q[x];
 31     q[x]:=len;
 32   end;
 33
 34 procedure spfa;
 35   var f,r,i,x,y:longint;
 36   begin
 37     f:=1;
 38     r:=1;
 39     st[1]:=1;
 40     for i:=2 to n do  //d[]表示根节点到其他节点的最短路
 41       d[i]:=2000000007;
 42     while f<=r do
 43     begin
 44       x:=st[f];
 45       i:=p[x];
 46       v[x]:=false;
 47       while i<>0 do
 48       begin
 49         y:=e[i].po;
 50         if d[y]>d[x]+e[i].num then
 51         begin
 52           d[y]:=d[x]+e[i].num;
 53           if not v[y] then
 54           begin
 55             inc(r);
 56             st[r]:=y;
 57             v[y]:=true;
 58           end;
 59         end;
 60         i:=e[i].next;
 61       end;
 62       inc(f);
 63     end;
 64   end;
 65
 66 procedure get(x,y:longint);
 67   begin
 68     inc(tot);
 69     while y<>x do
 70     begin
 71       mark[y]:=tot;  //环上节点(除最高点)标为同一颜色
 72       fadd(x,y);    //建“杨天”树
 73       y:=fa[y];
 74     end;
 75   end;
 76
 77 procedure dfs1(x:longint);
 78   var i,y:longint;
 79   begin
 80     inc(h);
 81     dfn[x]:=h;
 82     low[x]:=h;
 83     i:=p[x];
 84     while i<>0 do
 85     begin
 86       y:=e[i].po;
 87       if fa[x]<>y then
 88       begin
 89         if dfn[y]=0 then
 90         begin
 91           fa[y]:=x;
 92           dis[y]:=dis[x]+e[i].num;  //dis[]表示得到的dfs树上根节点到节点的距离
 93           dfs1(y);
 94         end;
 95         low[x]:=min(low[x],low[y]);
 96         if low[y]>dfn[x] then
 97           fadd(x,y);   //dfs树的树边
 98       end;
 99       i:=e[i].next;
100     end;
101     i:=p[x];
102     while i<>0 do
103     begin
104       y:=e[i].po;
105       if (dfn[y]>dfn[x]) and (fa[y]<>x) then
106       begin
107         get(x,y);  //处理环
108         s[tot]:=dis[y]-dis[x]+e[i].num;  //求这个环的长度
109       end;
110       i:=e[i].next;
111     end;
112   end;
113
114 procedure dfs2(x:longint);
115   var i,y:longint;
116   begin
117     for i:=1 to t do
118     begin
119       y:=anc[x,i-1];
120       if y<>0 then anc[x,i]:=anc[y,i-1] else break;
121     end;
122     i:=q[x];
123     while i<>0 do
124     begin
125       y:=w[i].po;
126       fa[y]:=x;
127       anc[y,0]:=x;
128       dep[y]:=dep[x]+1;  //在杨天树上的深度
129       dfs2(y);
130       i:=w[i].next;
131     end;
132   end;
133
134 function lca(x,y:longint):longint;
135   var i,p,a,b,z:longint;
136   begin
137     if x=y then exit(0);  //注意
138     if dep[x]<dep[y] then
139     begin
140       p:=x; x:=y; y:=p;
141     end;
142     a:=x;
143     b:=y;
144     p:=trunc(ln(dep[x])/ln(2));
145     if dep[a]>dep[b] then
146     begin
147       for i:=p downto 0 do
148         if dep[a]-1 shl i>=dep[b] then a:=anc[a,i];
149     end;
150     if a=b then exit(d[x]-d[a]);  //如果点a是点x的祖先那么a,x之间最短距离为d[x]-d[a]
151     for i:=p downto 0 do
152       if (anc[a,i]<>anc[b,i]) then
153       begin
154         a:=anc[a,i];
155         b:=anc[b,i];
156       end;
157     z:=fa[a];
158     if (mark[a]<>0) and (mark[a]=mark[b]) then  //最后提到环上两点要讨论
159     begin
160       p:=abs(dis[a]-dis[b]);
161       exit(d[x]-d[a]+d[y]-d[b]+min(p,s[mark[a]]-p));
162     end
163     else exit(d[x]+d[y]-2*d[z]);  //否则直接当树做
164   end;
165
166 begin
167   readln(n,m,qq);
168   for i:=1 to m do
169   begin
170     readln(x,y,z);
171     add(x,y,z);
172     add(y,x,z);
173   end;
174   t:=trunc(ln(n)/ln(2));
175   spfa;
176   len:=0;
177   dfs1(1);
178   dfs2(1);
179   for i:=1 to qq do
180   begin
181     readln(x,y);
182     writeln(lca(x,y));
183   end;
184 end.

View Code

转载于:https://www.cnblogs.com/phile/p/4472990.html

bzoj2125 3047相关推荐

  1. 大数据 防范脱贫人口返贫_男性比女性多出3047万,从人口大数据看,房价会涨还是跌?...

    由国家统计局发布的2019年中国人口数据,其中提到:截止2019年,中国男性人口比女性人口多了3047万! 好多未婚男青年背脊一凉,这是逼着去越南找对象吗?还是要凉凉打光棍的节奏? 新闻只指出数字,数 ...

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

    题意:仙人掌图最短路. 算法:圆方树DP,$O(n\log n+Q\log n)$ 首先建出仙人掌圆方树(与点双圆方树的区别在于直接连割边,也就是存在圆圆边),然后考虑点u-v的最短路径,显然就是:在 ...

  3. bzoj3047: Freda的传呼机bzoj2125: 最短路

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3047 http://www.lydsy.com/JudgeOnline/problem.ph ...

  4. HDU 3047 Zjnu Stadium (带权并查集)

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=3047 题目: Problem Description In 12th Zhejiang College ...

  5. 3047: 快速排序算法

    3047: 快速排序算法 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 287  Solved: 252 [Submit][Status][Web B ...

  6. BZOJ2125 最短路

    每个点有两个值,一个是从根到这个点的最短路d[i],一个是从根沿dfs树到这个点的距离rd[i]. 之后是一个很牛逼的建图,把环上的点都连到环中深度最浅的点得到一颗树,并维护每个点所在的环以及每个环的 ...

  7. hdu 3047 Zjnu Stadium(并查集)

    题意: 300个座位构成一个圈. 有N个人要入座. 共有M个说明 :A B X ,代表B坐在A顺时针方向第X个座位上.如果这个说明和之前的起冲突,则它是无效的. 问总共有多少个无效的. 思路: 并查集 ...

  8. [BZOJ2125]最短路

    Description 给一个N个点M条边的连通无向图,满足每条边最多属于一个环,有Q组询问,每次询问两点之间的最短路径. Input 输入的第一行包含三个整数,分别表示N和M和Q 下接M行,每行三个 ...

  9. 前端学习(3047):vue+element今日头条管理-使用table表格组件

最新文章

  1. 运维企业专题(7)LVS高可用与负载均衡中篇——VS/NAT模式配置详解
  2. 美国公司欲联合大电脑商阻止绿坝推广
  3. Crypto++入门学习笔记(DES、AES、RSA、SHA-256)
  4. 微盟涉嫌二清,大商户模式将受理严监管
  5. docker的安装与安装mysql(mac,centos为例)
  6. 《计算机网络:自顶向下方法(原书第6版)》一第1章
  7. 深度学习主流框架介绍(PyTorch、TensorFlow、Keras、Caffe、Theano、MXNET)
  8. 20190816 On Java8 第六章 初始化和清理
  9. 从这6个方面,帮你轻松管理Chrome中保存的密码!
  10. Android 10正式版发布,支持5G和折叠屏设备
  11. 《计算机网络》day01-网络的诞生和发展
  12. 0x00000....蓝屏
  13. 去掉电脑桌面图标中的箭头图标
  14. PXE启动芯片出错代码表初始化/引导/载入Bootstrap错误代码
  15. 分享一款在线视频播放器:h-player
  16. 曼妙琳珑心 Android 面试题(2)
  17. pve7 安装rhel9.0报错之Fatal glibc error: CPU does not support x86-64-v2处理及Kernel panic - not syncing
  18. 实验吧-密码学-疑惑的汉字(当铺密码)
  19. Android上好看的倒数日APP,Hurry:颜值超高的倒数日 App,让 Android 手机桌面好看 2 倍 #Android...
  20. PHP获取路径和目录方法总结

热门文章

  1. 人生就好比一场赌注 做好今天 活在当下
  2. linux rdesktop 远程,使用rdesktop实现从Ubuntu远程访问Windows桌面
  3. 同行不同命:极兔喜、韵达愁?
  4. C++模板元编程Type_traits
  5. chromatix 5.4.3安装打开失败license过期
  6. Wordpress 网站的复制和迁移
  7. Java制作简易画图板
  8. 谷歌去广告插件adblock安装方法
  9. 安卓期末复习——题库(一)
  10. 【转】快捷方式lnk文件格式详解(英文)