Description
雪之国度有N座城市,依次编号为1到N,又有M条道路连接了其中的城市,每一条道路都连接了不同的2个城市,任何两座不同的城市之间可能不止一条道路。雪之女王赋予了每一座城市不同的能量,其中第i座城市被赋予的能量为Wi。
如果城市u和v之间有一条道路,那么只要此刻雪之女王的能量不小于|Wu-Wv|,这条道路就是安全的。如果城市u和v之间存在两条没有重复道路的安全路径(其中每一段道路都是安全的),则认为这两座城市之间有着良好的贸易关系。
最近,雪之女王因为情感问题,她的能量产生巨大的波动。为了维持雪之国度的经济贸易,她希望你能帮忙对Q对城市进行调查。对于第j对城市uj和vj,她希望知道在保证这两座城市之间有着良好贸易关系的前提之下,自己最少需要保持多少的能量。
Input
每一组数据第一行有3个整数,依次为N,M,Q,表示城市个数,道路个数,和所需要进行的调查次数。
之后一行,有N个整数,依次为每一个城市被赋予的能量Wi。
之后M行,每一行有2个整数,表示对应编号的两个城市之间有一条道路。
之后Q行,每一行有2个整数,表示一组调查的城市目标。
(保证图联通!)
Output
输出一共有Q行,依次对应Q次调查的结果。其中第j行给出了第j次调查的结果,即雪之女王需要保持的最少能量值。如果永远也无法做到,输出”infinitely”。
Sample Input
7 8 4
3 2 4 1 3 5 9
1 2
1 3
2 4
2 5
3 6
6 7
4 6
5 6
4 5
4 6
5 6
2 7
Sample Output
4
4
2
infinitely
Data Constraint
对于20%的数据来说,3<=N<=10, 3<=M<=20, 1<=Q<=10
对于另30%的数据来说,Wi=0
对于100%的数据来说,3<=N<=100000, 3<=M<=500000, 1<=Q<=100000, 每一座城市的能量Wi满足0<=Wi<=200000.
分析:先跑一个最小生成树,此时两点已经有一条路径。然后对于不在最小生成树上的边按从小到大的顺序加入,每加入一条x到y的边,就把x到y路径上的全部点缩成一个点,形成新树,这个点的权就是加入这条边的权。把缩的点连成一棵树(并查集可以看作是把多棵子树合并),答案就是belong[x]到belong[y]上点的最大值。
代码:
const
maxn=100001;
maxv=500001;
type
code=record
x,y,w:longint;
end;
node=record
y,next:longint;
end;
var
n,m,test,o,k,e,ans:longint;
belong,ls,dep,fa,c,p:array [0..maxn] of longint;
bg,v:array [0..maxv] of boolean;
g:array [0..maxv] of code;
a:array [0..maxv] of longint;
adge:array [0..maxv] of node;
f,h:array [0..maxn,0..20] of longint;
procedure qsort(l,r:longint);
var
i,j,key:longint;
temp:code;
begin
if l>=r then exit;
i:=l;j:=r;
key:=g[l+random(r-l+1)].w;
repeat
while (g[i].w<key) do inc(i);
while (g[j].w>key) do dec(j);
if i<=j then
begin
temp:=g[i];g[i]:=g[j];g[j]:=temp;
inc(i);dec(j);
end;
until i>j;
qsort(l,j);
qsort(i,r);
end;
procedure add(x,y:longint);
begin
inc(o);
adge[o].y:=y;
adge[o].next:=ls[x];
ls[x]:=o;
end;
function find(x:longint):longint;
var root,y,w:longint;
begin
y:=x;
while p[y]>0 do
y:=p[y];
root:=y;
y:=x;
while p[y]>0 do
begin
w:=p[y];
p[y]:=root;
y:=w;
end;
find:=root;
end;
procedure union(x,y:longint);
var
u,v:longint;
begin
u:=find(x);
v:=find(y);
if u=v then exit;
p[v]:=u;
end;
procedure build_mst;
var i,sum:longint;
begin
sum:=0;
for i:=1 to m do
begin
if find(g[i].x)<>find(g[i].y) then
begin
bg[i]:=true;
union(g[i].x,g[i].y);
add(g[i].x,g[i].y);
add(g[i].y,g[i].x);
sum:=sum+1;
if sum=n-1 then exit;
end;
end;
end;
procedure dfs(x,fat:longint;depp:longint);
var t:longint;
begin
dep[x]:=depp;
fa[x]:=fat;
t:=ls[x];
while t>0 do
with adge[t] do
begin
if v[y]=false then
begin
v[y]:=true;
dfs(y,x,depp+1);
end;
t:=next;
end;
end;
procedure init;
var i,j:longint;
begin
readln(n,m,test);
for i:=1 to n do
read(a[i]);
for i:=1 to m do
begin
readln(g[i].x,g[i].y);
g[i].w:=abs(a[g[i].x]-a[g[i].y]);
end;
qsort(1,m);
end;
procedure up(x,y,z:longint);
var s,t,i:longint;
flag1,flag2:boolean;
begin
if find(x)=find(y) then exit;
k:=0; e:=e+1;
a[e]:=z;
while x<>y do
begin
s:=find(x);
t:=find(y);
flag1:=false; flag2:=false;
if s=x then begin s:=fa[x]; flag1:=true; end;
if t=y then begin t:=fa[y]; flag2:=true; end;
if dep[s]>=dep[t] then
begin
if flag1 then
begin
if belong[x]=0 then belong[x]:=e
else
begin
add(belong[x],e); add(e,belong[x]);
end;
k:=k+1;
c[k]:=x;
end
else
begin
add(belong[s],e);
add(e,belong[s]);
end;
x:=s;
end
else
begin
if flag2 then
begin
if belong[y]=0 then belong[y]:=e
else begin
add(belong[y],e); add(e,belong[y]);
end;
k:=k+1;
c[k]:=y;
end
else
begin
add(belong[t],e);
add(e,belong[t]);
end;
y:=t;
end;
end;
if belong[x]=0 then begin belong[x]:=e; k:=k+1; c[k]:=x; end
else
begin
add(belong[x],e);
add(e,belong[x]);
end;
for i:=1 to k do
union(x,c[i]);
end;
function max(x,y:longint):longint;
begin
if x>y then exit(x)
else exit(y);
end;
procedure lca(x,y:longint);
var t,s:longint;
begin
ans:=max(a[x],a[y]);
if dep[x]>dep[y] then
begin
x:=x xor y;
y:=x xor y;
x:=x xor y;
end;
s:=dep[y]-dep[x];
t:=20;
while t>=0 do
begin
if 1 shl t<=s then
begin
ans:=max(ans,h[y,t]);
y:=f[y,t];
s:=s-1 shl t;
end;
t:=t-1;
end;
if x=y then begin writeln(ans); exit; end;
t:=20;
while t>=0 do
begin
if f[x,t]<>f[y,t] then
begin
ans:=max(max(ans,h[x,t]),h[y,t]);
x:=f[x,t];
y:=f[y,t];
end;
t:=t-1;
end;
ans:=max(ans,a[fa[x]]);
writeln(ans);
end;
procedure main;
var i,j,x,y:longint;
begin
build_mst;
fillchar(p,sizeof(p),0);
v[1]:=true;
dfs(1,0,1);
o:=0;
fillchar(ls,sizeof(ls),0);
for i:=1 to m do
if bg[i]=false then
begin
up(g[i].x,g[i].y,g[i].w);
end;
fillchar(v,sizeof(v),false);
fillchar(dep,sizeof(dep),0);
for i:=1 to e do
begin
if v[i]=false then
begin
v[i]:=true;
dfs(i,0,1);
end;
end;
for i:=1 to e do
begin
f[i,0]:=fa[i];
h[i,0]:=a[fa[i]];
end;
for j:=1 to 20 do
for i:=1 to e do
begin
f[i,j]:=f[f[i,j-1],j-1];
h[i,j]:=max(h[i,j-1],h[f[i,j-1],j-1]);
end;
for i:=1 to test do
begin
readln(x,y);
if find(x)<>find(y) then writeln('infinitely')
else lca(belong[x],belong[y]);
end;
end;
begin
assign(input,'city.in');
assign(output,'city.out');
reset(input);
rewrite(output);
init;
main;
close(input);
close(output);
end.