货车运输(codevs 3287)题解
【问题描述】
A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。
【样例输入】
4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3
【样例输出】
3
-1
3
【解题思路】
本题为NOIP2013提高组day1第三题,首先我们可以看出这是一道求最大生成树的问题,用kruscal求出,对于我们要找的两个点,先判断是否有边相连,没有直接输出-1,然后将选中的边建成一棵带权树,接着我们求LCA来求两点之间的最小载重量,这里可以去看看LCA,我用的是倍增的方法,然后边求LCA边算两点到该点的最小值,最后输出即可。
【代码实现】
1 uses math; 2 const mi:array[0..14]of longint=(1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384); 3 var n,m,q,tot,i,j,x,y:longint; 4 a,b,v:array[0..50000]of longint; 5 fa,h:array[0..10000]of longint; 6 flag:array[0..10000]of boolean; 7 first,last,next,w:array[0..100000]of longint; 8 f,g:array[0..10000,0..14]of longint; 9 function gf(x:longint):longint; 10 begin 11 if fa[x]=x then 12 exit(x); 13 fa[x]:=gf(fa[x]); 14 exit(fa[x]); 15 end; 16 procedure swap(var x,y:longint); 17 var t:longint; 18 begin 19 t:=x; 20 x:=y; 21 y:=t; 22 end; 23 procedure sort(l,r: longint); 24 var 25 i,j,x,y: longint; 26 begin 27 i:=l; 28 j:=r; 29 x:=v[(l+r) div 2]; 30 repeat 31 while v[i]>x do 32 inc(i); 33 while x>v[j] do 34 dec(j); 35 if not(i>j) then 36 begin 37 swap(a[i],a[j]); 38 swap(b[i],b[j]); 39 swap(v[i],v[j]); 40 inc(i); 41 j:=j-1; 42 end; 43 until i>j; 44 if l<j then 45 sort(l,j); 46 if i<r then 47 sort(i,r); 48 end; 49 procedure insert(x,y,v:longint); 50 begin 51 inc(tot); 52 w[tot]:=v; 53 last[tot]:=y; 54 next[tot]:=first[x]; 55 first[x]:=tot; 56 end; 57 procedure dfs(x,dep:longint); 58 var i:longint; 59 begin 60 flag[x]:=true; 61 h[x]:=dep; 62 i:=first[x]; 63 while i<>0 do 64 begin 65 if not flag[last[i]] then 66 begin 67 f[last[i],0]:=x; 68 g[last[i],0]:=w[i]; 69 dfs(last[i],dep+1); 70 end; 71 i:=next[i]; 72 end; 73 end; 74 function ans(x,y:longint):longint; 75 var k:longint; 76 begin 77 ans:=maxlongint; 78 if h[x]<h[y] then 79 swap(x,y); 80 while h[x]>h[y] do 81 begin 82 k:=0; 83 while h[x]-h[y]>=mi[k+1] do 84 inc(k); 85 ans:=min(ans,g[x,k]); 86 x:=f[x,k]; 87 end; 88 while x<>y do 89 begin 90 if f[x,0]=f[y,0] then 91 begin 92 ans:=min(ans,min(g[x,0],g[y,0])); 93 break; 94 end; 95 k:=0; 96 while (f[x,k+1]<>f[y,k+1])and(h[x]>=mi[k+1]) do 97 inc(k); 98 ans:=min(ans,min(g[x,k],g[y,k])); 99 x:=f[x,k]; 100 y:=f[y,k]; 101 end; 102 end; 103 begin 104 readln(n,m); 105 for i:=1 to m do 106 readln(a[i],b[i],v[i]); 107 sort(1,m); 108 for i:=1 to n do 109 fa[i]:=i; 110 for i:=1 to m do 111 if gf(a[i])<>gf(b[i]) then 112 begin 113 fa[fa[a[i]]]:=fa[b[i]]; 114 insert(a[i],b[i],v[i]); 115 insert(b[i],a[i],v[i]); 116 end; 117 for i:=1 to n do 118 if not flag[i] then 119 dfs(1,0); 120 i:=1; 121 while mi[i]<n do 122 begin 123 for j:=1 to n do 124 if h[j]>=mi[i] then 125 begin 126 f[j,i]:=f[f[j,i-1],i-1]; 127 g[j,i]:=min(g[j,i-1],g[f[j,i-1],i-1]); 128 end; 129 inc(i); 130 end; 131 readln(q); 132 for i:=1 to q do 133 begin 134 readln(x,y); 135 if gf(x)=gf(y) then 136 writeln(ans(x,y)) 137 else 138 writeln(-1); 139 end; 140 end.