货车运输(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.

 

你可能感兴趣的:(code)