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
原文地址:https://www.cnblogs.com/Randolph87/p/3658469.html