• 【CF733F】Drivers Dissatisfaction(最小瓶颈生成树,倍增)


    题意:给出一个图,每条边有权值和花费c,每次花费c能使的权值-1。给出一个预算,求减完权值后的一个最小生成树。

    思路:感谢CC大神

            有这样一个结论:最佳方案里必定存在一种,预算全部花费全部分配在一条边上。证明显然,对于任意一组解,都可以在内部再分配预算使总费用更小或不变。

            于是先求出原图的最小生成树,枚举每条边。

            对于在生成树中的,判断使这条边减费是否更优。

            不在生成树上的,找出树上从x[i]到y[i]的路径(唯一)上a[i]最大的边,判断删除那条边并加入减费后的(x[i],y[i])是否更优。

      1 type yjs=record
      2           a:longint;
      3           s:int64;
      4          end;
      5 var f,q,g:array[1..210000,0..19]of longint;
      6     head,vet,next,len,num,a,b,c,x,y,dep,fa,inq,ya,yb:array[1..500000]of longint;
      7     hth,mst,s:int64;
      8     tot,n,m,i,del,k,tx,ty:longint;
      9     t:yjs;
     10 
     11 procedure swap(var x,y:longint);
     12 var t:longint;
     13 begin
     14  t:=x; x:=y; y:=t;
     15 end;
     16 
     17 procedure qsort(l,r:longint);
     18 var i,j,mid:longint;
     19 begin
     20  i:=l; j:=r; mid:=a[(l+r)>>1];
     21  repeat
     22   while mid>a[i] do inc(i);
     23   while mid<a[j] do dec(j);
     24   if i<=j then
     25   begin
     26    swap(a[i],a[j]); swap(b[i],b[j]); swap(c[i],c[j]);
     27    swap(x[i],x[j]); swap(y[i],y[j]);
     28    inc(i); dec(j);
     29   end;
     30  until i>j;
     31  if l<j then qsort(l,j);
     32  if i<r then qsort(i,r);
     33 end;
     34 
     35 procedure add(a,b,c,d:longint);
     36 begin
     37  inc(tot);
     38  next[tot]:=head[a];
     39  vet[tot]:=b;
     40  len[tot]:=c;
     41  num[tot]:=d;
     42  head[a]:=tot;
     43 end;
     44 
     45 function lca(x,y:longint):longint;
     46 var i,d:longint;
     47 begin
     48  if dep[x]<dep[y] then swap(x,y);
     49  d:=dep[x]-dep[y];
     50  for i:=0 to 19 do
     51   if d and (1<<i)>0 then x:=q[x,i];
     52  for i:=19 downto 0 do
     53   if q[x,i]<>q[y,i] then
     54   begin
     55    x:=q[x,i]; y:=q[y,i];
     56   end;
     57  if x=y then exit(x);
     58  exit(q[x,0]);
     59 end;
     60 
     61 function clac(x,y:longint):yjs;
     62 var i,d:longint;
     63     cc:yjs;
     64 begin
     65  if dep[x]<dep[y] then swap(x,y);
     66  d:=dep[x]-dep[y];
     67  cc.a:=0; cc.s:=-maxlongint;
     68  for i:=19 downto 0 do
     69   if d and (1<<i)>0 then
     70   begin
     71    if f[x,i]>cc.s then
     72    begin
     73     cc.a:=g[x,i];
     74     cc.s:=f[x,i];
     75    end;
     76    x:=q[x,i];
     77   end;
     78  exit(cc);
     79 end;
     80 
     81 function ask(x,y:longint):yjs;
     82 var t:longint;
     83     t1,t2:yjs;
     84 begin
     85  t:=lca(x,y);
     86  t1:=clac(x,t);
     87  t2:=clac(y,t);
     88  if t1.s>t2.s then exit(t1);
     89  exit(t2);
     90 end;
     91 
     92 function find(k:longint):longint;
     93 begin
     94  if fa[k]<>k then fa[k]:=find(fa[k]);
     95  find:=fa[k];
     96 end;
     97 
     98 procedure dfs(u,pre:longint);
     99 var e,v,i:longint;
    100 begin
    101  for i:=1 to 19 do
    102  begin
    103   if dep[u]<(1<<i) then break;
    104   q[u,i]:=q[q[u,i-1],i-1];
    105   if f[u,i-1]<f[q[u,i-1],i-1] then
    106   begin
    107    f[u,i]:=f[q[u,i-1],i-1];
    108    g[u,i]:=g[q[u,i-1],i-1];
    109   end
    110    else
    111    begin
    112     f[u,i]:=f[u,i-1];
    113     g[u,i]:=g[u,i-1];
    114    end;
    115  end;
    116  e:=head[u];
    117  while e<>0 do
    118  begin
    119   v:=vet[e];
    120   if v<>pre then
    121   begin
    122    dep[v]:=dep[u]+1;
    123    f[v,0]:=len[e];
    124    q[v,0]:=u;
    125    g[v,0]:=num[e];
    126    dfs(v,u);
    127   end;
    128   e:=next[e];
    129  end;
    130 end;
    131 
    132 begin
    133 
    134  readln(n,m);
    135  for i:=1 to m do read(a[i]);
    136  for i:=1 to m do read(b[i]);
    137  for i:=1 to m do c[i]:=i;
    138  for i:=1 to m do readln(x[i],y[i]);
    139  readln(s);
    140  ya:=a; yb:=b;
    141  qsort(1,m);
    142  for i:=1 to n do fa[i]:=i;
    143  for i:=1 to m do
    144  begin
    145   tx:=find(x[i]); ty:=find(y[i]);
    146   if tx<>ty then
    147   begin
    148    fa[ty]:=tx;
    149    hth:=hth+a[i];
    150    inq[c[i]]:=1;
    151    add(x[i],y[i],a[i],c[i]);
    152    add(y[i],x[i],a[i],c[i]);
    153   end;
    154  end;
    155  dfs(1,-1);
    156  mst:=hth;
    157  for i:=1 to m do
    158   if inq[c[i]]=1 then
    159   begin
    160    if mst-s div b[i]<hth then
    161    begin
    162     hth:=mst-s div b[i];
    163     k:=c[i];
    164    end;
    165   end
    166    else
    167    begin
    168     t:=ask(x[i],y[i]);
    169     if mst-ya[t.a]+a[i]-s div b[i]<hth then
    170     begin
    171      hth:=mst-ya[t.a]+a[i]-s div b[i];
    172      k:=c[i];
    173      del:=t.a;
    174     end;
    175    end;
    176  writeln(hth);
    177  for i:=1 to m do
    178  begin
    179   if i=del then continue;
    180   if i=k then begin writeln(i,' ',ya[i]-s div yb[i]); continue; end;
    181   if inq[i]=1 then writeln(i,' ',ya[i]);
    182  end;
    183 
    184 end.
  • 相关阅读:
    其他标签
    数组和全局变量
    字符串处理
    运算符
    PHP安装配置工具
    String、StringBuffer与StringBuilder之间区别
    mybits——1
    异常
    ubuntu 系统错误:Error : BrokenCount > 0解决
    ubuntu配置VScode
  • 原文地址:https://www.cnblogs.com/myx12345/p/6062000.html
Copyright © 2020-2023  润新知