lca问题的完美解决和升级!!!——预处理+二分深搜
来源:互联网 发布:angular ui router.js 编辑:程序博客网 时间:2024/05/17 03:26
良好应用:2013noip提高组day1压轴题货车运输
思路:可以明显看出是最大生成树,然后可以想到寻找路径,结果就是路径上的最小值(因为是树,所以路径是唯一的!)
最后就是如何求路径最小值了,可以先求出lca,同时预处理,完美地解决。
参考网址:程序写得很漂亮
参考程序(一遍过):
var
v:array[0..111000]of boolean;dp,mm:array[0..110000,0..20]of longint;
a,b,c,f,head,depth:array[0..110000]of longint;
e:array[0..110000]of record
j,w,next:longint;
end;
cnt,n,m:longint;
procedure openfile;
begin
assign(input,'truck.in');reset(input);
assign(output,'truck.out');rewrite(output);
end;
procedure closfile;
begin
close(input);close(output);
end;
function min(a,b:longint):longint;
begin
if a<b then exit(a);
exit(b);
end;
procedure init;
var
i:longint;
begin
readln(n,m);
for i:=1 to n do f[i]:=i;
for i:=1 to m do readln(a[i],b[i],c[i]);
end;
procedure kp(l,r:longint);
var
i,j,x,t:longint;
begin
i:=l;j:=r;x:=c[l+random(r-l+1)];
repeat
while c[i]>x do i:=i+1;
while c[j]<x do j:=j-1;
if i<=j then
begin
t:=c[i];c[i]:=c[j];c[j]:=t;
t:=a[i];a[i]:=a[j];a[j]:=t;
t:=b[i];b[i]:=b[j];b[j]:=t;
i:=i+1;j:=j-1;
end;
until i>j;
if i<r then kp(i,r);
if j>l then kp(l,j);
end;
{procedure newcode(u,v,i:longint);
begin
cnt:=cnt+1;
e[cnt].cap:=c[i];
e[cnt].u:=a[i];
e[cnt].v:=b[i];
end;}
procedure insert(u,v,c:longint);
begin
cnt:=cnt+1;
e[cnt].j:=v;e[cnt].w:=c;e[cnt].next:=head[u];head[u]:=cnt;
cnt:=cnt+1;
e[cnt].j:=u;e[cnt].w:=c;e[cnt].next:=head[v];head[v]:=cnt;
end;
function find(x:longint):longint;
begin
if f[x]<>x then f[x]:=find(f[x]);
exit(f[x]);
end;
procedure kruskal;
var
i,count,p,q:Longint;
begin
count:=0;
for i:=1 to m do
begin
p:=find(a[i]);q:=find(b[i]);
if p<>q then
begin
//newcode(a[i],b[i],i);
//newcode(b[i],a[i],i);
insert(a[i],b[i],c[i]);
insert(b[i],a[i],c[i]);
f[q]:=p;
count:=count+1;
if count=n-1 then break;
end;
end;
for i:=1 to n do f[i]:=find(i);
end;
procedure dfs(x,i:longint);
var
j,k:longint;
begin
v[x]:=true;depth[x]:=i;
j:=head[x];
while j>0 do
begin
if not v[e[j].j] then
begin
dp[e[j].j,0]:=x;mm[e[j].j,0]:=e[j].w;k:=0;
while dp[dp[e[j].j,k],k]<>0 do
begin
dp[e[j].j,k+1]:=dp[dp[e[j].j,k],k];
mm[e[j].j,k+1]:=min(mm[e[j].j,k],mm[dp[e[j].j,k],k]);
k:=k+1;
end;
dfs(e[j].j,i+1);
end;
j:=e[j].next;
end;
end;
procedure lca;
var
i:longint;
begin
for i:=1 to n do
if not v[i] then dfs(i,0);
end;
procedure prepare;
begin
randomize;
kp(1,m);
kruskal;
lca;
end;
function answer(x,y:longint):longint;
var
t,ans,k:longint;
begin
if depth[x]<depth[y] then
begin
t:=x;x:=y;y:=t;
end;
ans:=maxlongint;t:=depth[x]-depth[y];k:=0;
while t<>0 do
begin
if t and 1=1 then
begin
ans:=min(ans,mm[x,k]);
x:=dp[x,k];
end;
t:=t shr 1;
k:=k+1;
end;
k:=0;
while x<>y do
begin
if (dp[x,k]<>dp[y,k])or(k=0) then
begin
ans:=min(ans,min(mm[x,k],mm[y,k]));
x:=dp[x,k];y:=dp[y,k];
k:=k+1;
end
else k:=k-1;
end;
exit(ans);
end;
procedure solve;
var
q,from,tt:longint;
begin
readln(q);
for q:=1 to q do
begin
readln(from,tt);
if f[from]<>f[tt] then writeln(-1)
else writeln(answer(from,tt));
end;
end;
procedure main;
begin
openfile;
init;
prepare;
solve;
closfile;
end;
begin
main;
end.
1 0
- lca问题的完美解决和升级!!!——预处理+二分深搜
- 完美解决Android Studio升级3.0之后的Gradle问题
- 立波 iphone3gs越狱教程:成功把iphone3gs手机升级成ios6.1.3系统,完美越狱,解决no service和耗电量大的问题
- Android:完美解决listview的setonitemclicklistener 和 setontouchlistener冲突问题
- 完美解决View Pager和SlidingPaneLayout的滑动冲突问题
- 完美解决listView和ScrollView滑动冲突的问题
- 二分图的最佳完美匹配——KM算法
- LCA求法的三度升级
- 为xgboost搭建环境,升级glibc,gcc,和解决升级glibc之后的中文乱码问题
- sscanf引发的Heap corruption detected error问题——有待完美解决
- 完美解决:Apache启动问题—(OS 10022)提供了一个无效的参数
- 解决IE6下PNG不透明问题—DD_belatedPNG的完美方案
- ajax完美解决的一个麻烦问题
- ajax完美解决的一个麻烦问题
- ajax完美解决的一个麻烦问题
- ajax完美解决的一个麻烦问题
- 完美解决E73的中文字体问题
- 完美解决水晶报表的翻页问题
- hdu 5505
- lua文件读写
- 一个大四求职的菜鸟的web前端学习之路(二)
- 代码重构---代码大全学习系列--未完成
- Leetcode -- Divide Two Integers
- lca问题的完美解决和升级!!!——预处理+二分深搜
- hadoop学习笔记之<hadoop fs命令详解>
- CODEVS1576最长严格上升子序列
- ios教程(java编程思想等级)
- Android —— 下拉刷新和上拉加载功能实现
- git学习
- 线程休眠+内部类构建=龟兔赛跑
- 【日常学习】【树形DP】【树的最小点覆盖】tyvj1377 荒山突围题解
- python数据结构——排序算法——八大排序算法的Python实现