3732: Network

时间:2023-03-10 04:23:51
3732: Network

3732: Network

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 395  Solved: 179
[Submit][Status]

Description

给你N个点的无向图 (1 <= N <= 15,000),记为:1…N。 
图中有M条边 (1 <= M <= 30,000) ,第j条边的长度为: d_j ( 1 < = d_j < = 1,000,000,000).

现在有 K个询问 (1 < = K < = 15,000)。 
每个询问的格式是:A B,表示询问从A点走到B点的所有路径中,最长的边最小值是多少?

Input

第一行: N, M, K。 
第2..M+1行: 三个正整数:X, Y, and D (1 <= X <=N; 1 <= Y <= N). 表示X与Y之间有一条长度为D的边。 
第M+2..M+K+1行: 每行两个整数A B,表示询问从A点走到B点的所有路径中,最长的边最小值是多少?

Output

对每个询问,输出最长的边最小值是多少。

Sample Input

6 6 8
1 2 5
2 3 4
3 4 3
1 4 8
2 5 7
4 6 2
1 2
1 3
1 4
2 3
2 4
5 1
6 2
6 1

Sample Output

5
5
5
4
4
7
4
5

HINT

1 <= N <= 15,000

1 <= M <= 30,000

1 <= d_j <= 1,000,000,000

1 <= K <= 15,000

Source

题解:简直逗比到家啊——昨天我的程序先是TLE,但是一想这个复杂度应该不会啊,感觉不对头,于是发现了数组开小了(phile:数组开小怎么会TLE? HansBug:我哪知道= =)然后再交就WA,不停的WA,我硬是找了一个晚上的错,结果啥都没弄出来,还是那样,弃疗了,向lydsy2012要了下数据。。。今天数据到手,手工一测试,怎么测都没错?!?!然后再Submit一次一个字都没动的程序,Accept(HansBug:这。。。)。。。好了说思路——这题可以算是NOIP2013货车运输的修改+略微强化版,先是求出最小生成树(额。。我一般用并查集+kruskal),然后DFS建树,然后用倍增进行O(nlogn)的初始化,然后每次一个O(logn)地求LCA(至于路径上的最大值嘛,只要再加一个数组就行啦),就这样O(nlogn)地AC之。。。(HansBug:不过这个逗比的Judge还是害得我纠结了一晚上啊TT phile:不是和你说了嘛变量不清零有时候会跪掉。。。 HansBug:GET IT。。。)
 type
point=^node;
node=record
w,g:longint;
next:point;
end; var
i,j,k,l,m,n,t:longint;
a:array[..] of point;
b:array[..,..] of longint;
c,f,g,h:array[..] of longint;
d:array[..,..] of longint;
e:array[..,..] of longint;
function getfat(x:longint):longint;inline;
begin
while x<>c[x] do x:=c[x];
getfat:=x;
end;
function tog(x,y:longint):boolean;inline;
begin
exit(getfat(x)=getfat(y));
end;
procedure merge(x,y:longint);inline;
begin
c[getfat(x)]:=getfat(y);
end; procedure add(x,y,z:longint);inline;
var p:point;
begin
new(p);
p^.g:=y;
p^.w:=z;
p^.next:=a[x];
a[x]:=p;
end;
procedure swap(var x,y:longint);inline;
var z:longint;
begin
z:=x;x:=y;y:=z;
end;
procedure sort(l,r:longint);inline;
var i,j,x,y:longint;
begin
i:=l;j:=r;x:=b[(l+r) div ,];
repeat
while b[i,]<x do inc(i);
while b[j,]>x do dec(j);
if i<=j then
begin
swap(b[i,],b[j,]);
swap(b[i,],b[j,]);
swap(b[i,],b[j,]);
inc(i);dec(j);
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end;
procedure dfs(x:longint);inline;
var p:point;
begin
p:=a[x];
while p<>nil do
begin
if d[,p^.g]= then
begin
d[,p^.g]:=x;
e[,p^.g]:=p^.w;
c[p^.g]:=c[x]+;
dfs(p^.g);
end;
p:=p^.next;
end;
end;
function max(x,y:longint):longint;inline;
begin
if x>y then max:=x else max:=y;
end;
function fatget(x,y:longint):longint;//inline;
var i:longint;
begin
i:=;
while y> do
begin
if odd(y) then x:=d[i,x];
inc(i);
y:=y div ;
end;
exit(x);
end;
function getmax(x,y:longint):longint;//inline;
var i,j:longint;
begin
i:=;j:=;
while y> do
begin
if odd(y) then
begin
j:=max(j,e[i,x]);
x:=d[i,x];
end;
inc(i);
y:=y div ;
end;
exit(j);
end;
function getcom(x,y:longint):longint;//inline;
var i,j,k,l:longint;
begin
if x=y then exit(x);
if c[x]<c[y] then swap(x,y);
x:=fatget(x,c[x]-c[y]);
if x=y then exit(x);
i:=;
while i>= do
begin
if d[i,x]<>d[i,y] then
begin
x:=d[i,x];
y:=d[i,y];
end;
dec(i);
end;
exit(d[,x]);
end;
function getpath(x,y:longint):longint;//inline;
var i,j,k,l:longint;
begin
l:=getcom(x,y);
getpath:=max(getmax(x,c[x]-c[l]),getmax(y,c[y]-c[l]));
end; begin
readln(n,m,t);
for i:= to n do a[i]:=nil;
for i:= to n do c[i]:=i;
for i:= to m do
readln(b[i,],b[i,],b[i,]);
sort(,m);
j:=;
for i:= to n- do
begin
while tog(b[j,],b[j,]) do inc(j);
add(b[j,],b[j,],b[j,]);
add(b[j,],b[j,],b[j,]);
merge(b[j,],b[j,]);
end;
fillchar(d,sizeof(d),);
fillchar(c,sizeof(c),);
d[,]:=-;
dfs();
d[,]:=;
for i:= to do
begin
for j:= to n do
begin
d[i,j]:=d[i-,d[i-,j]];
e[i,j]:=max(e[i-,d[i-,j]],e[i-,j]);
end;
end;
for i:= to t do
begin
readln(j,k);
writeln(getpath(j,k));
end;
end.