博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Codevs1519]过路费解题报告|最小生成树|LCA
阅读量:5045 次
发布时间:2019-06-12

本文共 3211 字,大约阅读时间需要 10 分钟。

   在某个遥远的国家里,有 n个城市。编号为 1,2,3,…,n。这个国家的政府修建了m 条双向道路,每条道路连接着两个城市。政府规定从城市 S 到城市T需要收取的过路费为所经过城市之间道路长度的最大值。如:A到B长度为 2,B到C 长度为3,那么开车从 A经过 B到C 需要上交的过路费为 3。

    佳佳是个做生意的人,需要经常开车从任意一个城市到另外一个城市,因此他需要频繁地上交过路费,由于忙于做生意,所以他无时间来寻找交过路费最低的行驶路线。然而, 当他交的过路费越多他的心情就变得越糟糕。 作为秘书的你,需要每次根据老板的起止城市,提供给他从开始城市到达目的城市,最少需要上交多少过路费。

 

  这道题的数据范围比较大,n<=10^5,q<=10^4

  所以解决每一个询问的时间不能太大

  我们考虑两点间的路径中边权最大值最小的路径

  突然联想到最小生成树的性质之一:整棵树中最大的边权最小

  和我们的条件有一点相似但也不大一样

  那是否两点间路径中边权最大值最小的路径一定在最小生成树中呢?

  我们先假设不成立,即树上两点u,v之间存在一条路径中的最大值d

  小于生成树上u,v之间路径上的最大值x

  然后考虑最小生成树的Kruskal过程,我们将所有的边边权从小到大加入

  那么显然,如果u,v间的所有边边权都小于x,那么在x加入之前u,v必然已经达到联通状态

  所以这种情况是不可能出现的

  

  所以任意两点间路径中最大边权最小的路径必定在整张图的最小生成树中

  这一点得证之后,对于每个询问,O(logn)的倍增查找就可以了

 

program xjt1;const maxm = 200010;maxn = 10010;var n,m,i,x,y,z,e,q:longint;    ter,next,w:array[-1..maxm]of longint;    link,fat,dep:array[-1..maxn]of longint;    a:array[-1..maxm]of record x,y,z:longint;end;    dis,fa:array[-1..maxn,-1..25]of longint;function max(a,b:longint):longint;begin    if a>b then exit(a) else exit(b);end;procedure add(x,y,z:longint);begin    inc(e);ter[e]:=y;next[e]:=link[x];link[x]:=e;w[e]:=z;    inc(e);ter[e]:=x;next[e]:=link[y];link[y]:=e;w[e]:=z;end;procedure qsort(L,R:longint);var i,j,mid:longint;begin    i:=L;j:=R;mid:=a[random(R-L+1)+L].z;    repeat        while (i
mid) do dec(j); if i<=j then begin a[0]:=a[i];a[i]:=a[j];a[j]:=a[0]; inc(i);dec(j); end; until i>j; if i
<< i then break; fa[p][i]:=fa[fa[p][i-1]][i-1]; dis[p][i]:=max(dis[p][i-1],dis[fa[p][i-1]][i-1]) end; j:=link[p]; while j<>0 do begin if dep[ter[j]]=0 then begin dep[ter[j]]:=dep[p]+1; fa[ter[j]][0]:=p; dis[ter[j]][0]:=w[j]; dfs(ter[j]); end; j:=next[j]; end;end;function lca(x,y:longint):longint;var i,tem:longint;begin if x = y then exit(0); lca:=0; if dep[x]
dep[y] then begin i:=trunc(ln(dep[x]-dep[y])/ln(2)); while dep[x]>dep[y] do begin while dep[x]-dep[y]>=1 << i do begin lca:=max(lca,dis[x][i]); x:=fa[x][i]; end; dec(i); end; end; if x <> y then begin i:=trunc(ln(n)/ln(2)); while fa[x][0]<>fa[y][0] do begin while fa[x][i]<>fa[y][i] do begin lca:=max(max(lca,dis[x][i]),dis[y][i]); x:=fa[x][i];y:=fa[y][i]; end; dec(i); end; lca:=max(lca,dis[x][0]); lca:=max(lca,dis[y][0]); end;end;begin readln(n,m);e:=0; for i:=1 to m do with a[i] do begin readln(x,y,z); end; qsort(1,m); for i:=1 to n do fat[i]:=i; for i:=1 to m do begin x:=getfa(a[i].x);y:=getfa(a[i].y); if x<>y then begin fat[x]:=y; // writeln(a[i].z); add(a[i].x,a[i].y,a[i].z); end; end; dep[1]:=1;dfs(1); readln(q); for i:=1 to q do begin readln(x,y); writeln(lca(x,y)); end;end.

 

 

 

  

转载于:https://www.cnblogs.com/mjy0724/p/4463065.html

你可能感兴趣的文章
结对第二次作业
查看>>
jQuery 1.7的隐藏改动
查看>>
初学ant
查看>>
bzoj 4295 [PA2015]Hazard 贪心,暴力
查看>>
HTML5实践 -- 使用css装饰你的图片画廊
查看>>
软件工程总结
查看>>
解决PowerDesigner 16 Generate Datebase For Sql2005/2008 对象名sysproperties无效的问题
查看>>
learning ddr seft-refresh mode summary
查看>>
30款超酷的HTTP 404页面未找到错误设计
查看>>
【简报】kube框架结构-一个小型响应式CSS框架
查看>>
帮助快速生成页面固定显示元素的jQuery插件 - sticky-kit
查看>>
Java IO-6 打印流
查看>>
数据结构--归并排序的应用(求逆序数 蓝桥杯--小朋友排队)
查看>>
RabbitMQ 消息顺序、消息幂等、消息重复、消息事务、集群
查看>>
k64 datasheet学习笔记1---概述
查看>>
LeetCode 121 Best Time to Buy and Sell Stock
查看>>
Lambda 表达式的示例
查看>>
linux文件系统初始化过程(1)---概述
查看>>
NIO
查看>>
FASTREPORT 整理 (mtm)
查看>>