3287 货车运输
2013年NOIP全国联赛提高组A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。
第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道路。
接下来 m 行每行 3 个整数 x、y、z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。注意:x 不等于 y,两座城市之间可能有多条道路。
接下来一行有一个整数 q,表示有 q 辆货车需要运货。
接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意:x 不等于 y。
输出共有 q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货车不能到达目的地,输出-1。
4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3
3
-1
3
对于 30%的数据,0 < n < 1,000,0 < m < 10,000,0 < q < 1,000;
对于 60%的数据,0 < n < 1,000,0 < m < 50,000,0 < q < 1,000;
对于 100%的数据,0 < n < 10,000,0 < m < 50,000,0 < q < 30,000,0 ≤ z ≤ 100,000。
分类标签 Tags 点此展开
题解:本来想把这道题当作个娱乐的,可是一写就逗比了,然后疯狂查错,查得要疯了——结果发现一开始快排写错了(HansBug:巨汗*_* phile:我也是醉疯了)
别的不难,思路就是——先最大生成树,然后每次只要访问在这棵树上面的路径的瓶颈值即可,我用了下lca算法,可是看样子时间相当之充裕让我都吓了一跳,所以估计就算是暴力找路的话估计也能差不多AC么么哒
1 type 2 point=^node; 3 node=record 4 g,w:longint; 5 next:point; 6 end; 7 var 8 i,j,k,l,m,n,tt,t,yy:longint; 9 a:array[0..70000,1..3] of longint; 10 c,ct,f:array[0..10050] of longint; 11 d,e:array[0..30,0..10050] of longint; 12 b:array[0..10050] of point; 13 function max(x,y:longint):longint; 14 begin 15 if x>y then max:=x else max:=y; 16 end; 17 function min(x,y:longint):longint; 18 begin 19 if x<y then min:=x else min:=y; 20 end; 21 function getfat(x:longint):longint; 22 begin 23 if x<>c[x] then c[x]:=getfat(c[x]); 24 exit(c[x]); 25 end; 26 procedure merge(x,y:longint); 27 var a1,a2:longint; 28 begin 29 a1:=getfat(x);a2:=getfat(y); 30 if a1=a2 then exit; 31 c[getfat(x)]:=getfat(y); 32 dec(tt); 33 end; 34 function tog(x,y:longint):boolean; 35 begin 36 exit(getfat(x)=getfat(Y)); 37 end; 38 procedure swap(var x,y:longint); 39 var z:longint; 40 begin 41 z:=x;x:=y;y:=z; 42 end; 43 procedure sort(l,r:longint); 44 var i,j,x,y:longint; 45 begin 46 i:=l;j:=r;x:=a[(l+r) div 2,3]; 47 repeat 48 while a[i,3]>x do inc(i); 49 while a[j,3]<x do dec(j); 50 if i<=j then 51 begin 52 swap(a[i,1],a[j,1]); 53 swap(a[i,2],a[j,2]); 54 swap(a[i,3],a[j,3]); 55 inc(i);dec(j); 56 end; 57 until i>j; 58 if i<r then sort(i,r); 59 if l<j then sort(l,j); 60 end; 61 procedure add(x,y,z:longint); 62 var p:point; 63 begin 64 new(p); 65 p^.w:=z;p^.g:=y; 66 p^.next:=b[x];b[x]:=p; 67 end; 68 procedure dfs(x:longint); 69 var p:point; 70 begin 71 p:=b[x]; 72 while p<>nil do 73 begin 74 if d[0,p^.g]=0 then 75 begin 76 d[0,p^.g]:=x; 77 e[0,p^.g]:=p^.w; 78 f[p^.g]:=f[x]+1; 79 dfs(p^.g); 80 end; 81 p:=p^.next; 82 end; 83 end; 84 function fatfat(x,y:longint):longint; 85 var i,j:longint; 86 begin 87 i:=0; 88 while y>0 do 89 begin 90 if odd(y) then x:=d[i,x]; 91 inc(i);y:=y div 2; 92 end; 93 exit(x); 94 end; 95 function fatlen(x,y:longint):longint; 96 var i,j:longint; 97 begin 98 i:=0;j:=maxlongint; 99 while y>0 do 100 begin 101 if odd(y) then 102 begin 103 j:=min(j,e[i,x]); 104 x:=d[i,x]; 105 end; 106 inc(i);y:=y div 2; 107 end; 108 exit(j); 109 end; 110 function getlent(x,y:longint):longint; 111 var a1,a2,a3,a4,i:longint; 112 begin 113 if c[x]<>c[y] then exit(-1); 114 if f[x]<f[y] then swap(x,y); 115 a3:=x;a4:=y; 116 x:=fatfat(x,f[x]-f[y]); 117 if x=y then exit(fatlen(a3,f[a3]-f[a4])); 118 for i:=30 downto 0 do 119 begin 120 if not((d[i,x]=0) or (d[i,x]=d[i,y])) then 121 begin 122 x:=d[i,x]; 123 y:=d[i,y]; 124 end; 125 end; 126 a1:=d[0,x]; 127 exit(min(fatlen(a4,f[a4]-f[a1]),fatlen(a3,f[a3]-f[a1]))); 128 end; 129 begin 130 readln(n,m); 131 for i:=1 to m do readln(a[i,1],a[i,2],a[i,3]); 132 sort(1,m); 133 FOR I:=1 to n do c[i]:=i; 134 tt:=n; 135 for i:=1 to m do 136 merge(a[i,1],a[i,2]); 137 for i:=1 to n do c[i]:=i; 138 for i:=1 to n do b[i]:=nil; 139 j:=0; 140 fillchar(d,sizeof(d),0);yy:=tt; 141 for i:=1 to n-yy do 142 begin 143 inc(j); 144 while tog(a[j,1],a[j,2]) do inc(j); 145 add(a[j,1],a[j,2],a[j,3]); 146 add(a[j,2],a[j,1],a[j,3]); 147 merge(a[j,1],a[j,2]); 148 end; 149 for i:=1 to n do c[i]:=getfat(c[i]); 150 fillchar(ct,sizeof(ct),0); 151 fillchar(f,sizeof(f),0); 152 for i:=1 to n do 153 begin 154 if ct[c[i]]=0 then 155 begin 156 ct[c[i]]:=1; 157 d[0,i]:=-1; 158 dfs(i); 159 d[0,i]:=0; 160 end; 161 end; 162 for i:=1 to 30 do 163 for j:=1 to n do 164 begin 165 d[i,j]:=d[i-1,d[i-1,j]]; 166 if (e[i-1,d[i-1,j]]<>0) and (e[i-1,j]<>0) then 167 e[i,j]:=min(e[i-1,d[i-1,j]],e[i-1,j]) 168 else 169 begin 170 if e[i-1,d[i-1,j]]=0 then 171 begin 172 if e[i-1,j]=0 then 173 e[i,j]:=maxlongint 174 else 175 e[i,j]:=e[i-1,j] 176 177 end 178 else 179 e[i,j]:=e[i-1,d[i-1,j]]; 180 end; 181 end; 182 readln(t); 183 for i:=1 to t do 184 begin 185 readln(j,k); 186 writeln(getlent(j,k)); 187 end; 188 readln; 189 end. 190