• 货车运输(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.
  • 相关阅读:
    二叉树解题思想
    SpringBoot + Mybatis 和ssm 使用数据库的区别
    Spring Cache 抽象(缓存抽象) Redis 缓存
    VirtualBox 虚拟机 从入门到入坑
    小知识点的记录
    SpringBoot 的不同
    请你激起学习的激情
    java 适配器模式
    UML类图的情话诉说
    Java 工厂模式
  • 原文地址:https://www.cnblogs.com/PengBoLiuXu/p/4550037.html
Copyright © 2020-2023  润新知