貨車運輸(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.

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章