• 2001: [Hnoi2010]City 城市建设


    Description
    PS国是一个拥有诸多城市的大国,国王Louis为城市的交通建设可谓绞尽脑汁。Louis可以在某些城市之间修建道路,在不同的城市之间修建道路需要不同的花费。Louis希望建造最少的道路使得国内所有的城市连通。但是由于某些因素,城市之间修建道路需要的花费会随着时间而改变,Louis会不断得到某道路的修建代价改变的消息,他希望每得到一条消息后能立即知道使城市连通的最小花费总和, Louis决定求助于你来完成这个任务。
    Input
    文件第一行包含三个整数N,M,Q,分别表示城市的数目,可以修建的道路个数,及收到的消息个数。 接下来M行,第i+1行有三个用空格隔开的整数Xi,Yi,Zi(1≤Xi,Yi≤n, 0≤Zi≤50000000),表示在城市Xi与城市Yi之间修建道路的代价为Zi。接下来Q行,每行包含两个数k,d,表示输入的第k个道路的修建代价修改为d(即将Zk修改为d)。
    Output
    输出包含Q行,第i行输出得知前i条消息后使城市连通的最小花费总和。
    Sample Input
    5 5 3
    1 2 1
    2 3 2
    3 4 3
    4 5 4
    5 1 5
    1 6
    1 1
    5 3

    Sample Output
    14
    10
    9
    HINT

    【数据规模】
    对于20%的数据, n≤1000,m≤6000,Q≤6000。
    有20%的数据,n≤1000,m≤50000,Q≤8000,修改后的代价不会比之前的代价低。
    对于100%的数据, n≤20000,m≤50000,Q≤50000。

    在机房小伙伴z55250825的耐心讲解下,认真的把他的代码抄了一遍(卧槽,还抄错了一次,卧槽,抄错的地方竟然是并查集的地方)

    论文61页就是这道题,可以看一下

    反正我是这么想的,这个分治是这样的

    slove(l,r)

    先把这个区间生成树的一定会选的边求出,把不需要的边删除,看起来好人性化的样子

    contraction就是把一定会选的边计算出来,reduction就是把不会选的边去掉

    论文中证明了它的复杂度,做法也在里面了,我就不说什么了,反正我也不会说

    代码基本上是抄z55250825的,因为不会写啊

      1 const
      2         maxn=50010;
      3         inf=maxlongint;
      4 type
      5         edge=record
      6           u,v,w,k:longint;
      7         end;
      8         g=array[0..maxn]of edge;
      9 var
     10         e:array[0..16]of g;
     11         t,tt:g;
     12         f,d,size,qx,qy,sum,aa,pos:array[0..maxn]of longint;
     13         ans:array[0..maxn]of int64;
     14         n,m,q:longint;
     15  
     16 function find(x:longint):longint;
     17 begin
     18         if f[x]=x then exit(x);
     19         f[x]:=find(f[x]);
     20         exit(f[x]);
     21 end;
     22  
     23 procedure union(u,v:longint);
     24 begin
     25         if u=v then exit;
     26         if size[u]<size[v] then
     27           begin
     28             f[u]:=v;
     29             inc(size[v],size[u]);
     30           end
     31         else
     32           begin
     33             f[v]:=u;
     34             inc(size[u],size[v]);
     35           end;
     36 end;
     37  
     38 procedure sort(l,r:longint;var a:g);
     39 var
     40         i,j,y:longint;
     41         t:edge;
     42 begin
     43         i:=l;
     44         j:=r;
     45         y:=a[(l+r)>>1].w;
     46         repeat
     47           while a[i].w<y do
     48             inc(i);
     49           while a[j].w>y do
     50             dec(j);
     51           if i<=j then
     52           begin
     53             t:=a[i];
     54             a[i]:=a[j];
     55             a[j]:=t;
     56             inc(i);
     57             dec(j);
     58           end;
     59         until i>j;
     60         if i<r then sort(i,r,a);
     61         if j>l then sort(l,j,a);
     62 end;
     63  
     64 procedure contraction(var tot:longint;var cnt:int64);
     65 var
     66         i,tmp,u,v:longint;
     67 begin
     68         tmp:=0;
     69         for i:=1 to tot do
     70           begin
     71             f[t[i].u]:=t[i].u;
     72             f[t[i].v]:=t[i].v;
     73             size[t[i].u]:=1;
     74             size[t[i].v]:=1;
     75           end;
     76         sort(1,tot,t);
     77         for i:=1 to tot do
     78           begin
     79             u:=find(t[i].u);
     80             v:=find(t[i].v);
     81             if u=v then continue;
     82             union(u,v);
     83             inc(tmp);
     84             tt[tmp]:=t[i];
     85           end;
     86         for i:=1 to tmp do
     87           begin
     88             f[tt[i].u]:=tt[i].u;
     89             f[tt[i].v]:=tt[i].v;
     90             size[tt[i].u]:=1;
     91             size[tt[i].v]:=1;
     92           end;
     93         for i:=1 to tmp do
     94           if tt[i].w<>-inf then
     95           begin
     96             u:=find(tt[i].u);
     97             v:=find(tt[i].v);
     98             if u=v then continue;
     99             union(u,v);
    100             inc(cnt,tt[i].w);
    101           end;
    102         tmp:=0;
    103         for i:=1 to tot do
    104           if find(t[i].u)<>find(t[i].v) then
    105           begin
    106             inc(tmp);
    107             tt[tmp]:=t[i];
    108             pos[t[i].k]:=tmp;
    109             tt[tmp].u:=f[t[i].u];
    110             tt[tmp].v:=f[t[i].v];
    111           end;
    112         for i:=1 to tmp do
    113           t[i]:=tt[i];
    114         tot:=tmp;
    115 end;
    116  
    117 procedure reduction(var tot:longint);
    118 var
    119         i,tmp,u,v:longint;
    120 begin
    121         tmp:=0;
    122         for i:=1 to tot do
    123           begin
    124             f[t[i].u]:=t[i].u;
    125             f[t[i].v]:=t[i].v;
    126             size[t[i].u]:=1;
    127             size[t[i].v]:=1;
    128           end;
    129         sort(1,tot,t);
    130         for i:=1 to tot do
    131           if (find(t[i].u)<>find(t[i].v)) or (t[i].w=inf) then
    132           begin
    133             union(f[t[i].u],f[t[i].v]);
    134             inc(tmp);
    135             tt[tmp]:=t[i];
    136           end;
    137         for i:=1 to tmp do
    138           t[i]:=tt[i];
    139         tot:=tmp;
    140 end;
    141  
    142 procedure slove(dep,l,r:longint;cnt:int64);
    143 var
    144         i,mid:longint;
    145 begin
    146         if l=r then aa[qx[l]]:=qy[l];
    147         for i:=1 to sum[dep] do
    148           with e[dep][i] do
    149             w:=aa[k];
    150         for i:=1 to sum[dep] do
    151           begin
    152             t[i]:=e[dep][i];
    153             pos[t[i].k]:=i;
    154           end;
    155         if l=r then
    156         begin
    157           ans[l]:=cnt;
    158           for i:=1 to sum[dep] do
    159             begin
    160               f[t[i].u]:=t[i].u;
    161               f[t[i].v]:=t[i].v;
    162               size[t[i].u]:=1;
    163               size[t[i].v]:=1;
    164             end;
    165           sort(1,sum[dep],t);
    166           for i:=1 to sum[dep] do
    167             if find(t[i].u)<>find(t[i].v) then
    168             begin
    169               union(f[t[i].u],f[t[i].v]);
    170               inc(ans[l],t[i].w);
    171             end;
    172           exit;
    173         end;
    174         sum[dep+1]:=sum[dep];
    175         for i:=l to r do
    176           t[pos[qx[i]]].w:=-inf;
    177         contraction(sum[dep+1],cnt);
    178         for i:=l to r do
    179           t[pos[qx[i]]].w:=inf;
    180         reduction(sum[dep+1]);
    181         for i:=1 to sum[dep+1] do
    182           e[dep+1][i]:=t[i];
    183         mid:=(l+r)>>1;
    184         slove(dep+1,l,mid,cnt);
    185         slove(dep+1,mid+1,r,cnt);
    186 end;
    187  
    188 procedure init;
    189 var
    190         i:longint;
    191 begin
    192         read(n,m,q);
    193         sum[0]:=m;
    194         for i:=1 to m do
    195           with e[0][i] do
    196             begin
    197               read(u,v,w);
    198               k:=i;
    199               aa[i]:=w;
    200             end;
    201         for i:=1 to q do
    202           read(qx[i],qy[i]);
    203 end;
    204  
    205 procedure work;
    206 var
    207         i:longint;
    208 begin
    209         slove(0,1,q,0);
    210         for i:=1 to q do
    211           writeln(ans[i]);
    212 end;
    213  
    214 begin
    215         init;
    216         work;
    217 end.
    View Code
  • 相关阅读:
    Linux的中文输入法Fcitx-国货精品
    Linux内核编译与安装[转]
    Linux内核编译与安装[转]
    修改镜像地址加快Ubuntu更新速度
    修改镜像地址加快Ubuntu更新速度
    OSX操作技巧:快速锁定系统(类似Windows+L)
    NDK编程入门笔记[转]
    NDK编程入门笔记[转]
    内置函数图形分类
    函数的定义
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3658469.html
Copyright © 2020-2023  润新知