bzoj3669

不难想到从小到大穷举a,判断在携带不超过a个B型精灵的情况下最少携带多少个B型精灵
这是一个经典的问题,显然要求出最小生成树,树上1到N路径上最大的边即是答案
所以我们要动态维护一个最小生成树可以用link cut tree维护
根据最小生成树的回路性质,我们加入一条边(u,v),保留树上u-v路径上最大边和新边中小的那个
由于这里维护的是边权,我们可以把每条边当做一个点p(u,v),连接(u,v)时,即是连接(u,p)和(v,p)
然后记录下路径上最大点权的编号即可

  1 var son:array[0..150010,1..2] of longint;
  2     q,f,w,fa,v:array[0..150010] of longint;
  3     rev:array[0..150010] of boolean;
  4     s,e,a,b:array[0..150010] of longint;
  5     ans,i,n,m:longint;
  6 
  7 function min(a,b:longint):longint;
  8   begin
  9     if a>b then exit(b) else exit(a);
 10   end;
 11 
 12 function getf(x:longint):longint;
 13   begin
 14     if f[x]<>x then f[x]:=getf(f[x]);
 15     exit(f[x]);
 16   end;
 17 
 18 procedure swap(var a,b:longint);
 19   var c:longint;
 20   begin
 21     c:=a;
 22     a:=b;
 23     b:=c;
 24   end;
 25 
 26 function root(x:longint):boolean;
 27   begin
 28     exit((son[fa[x],1]<>x) and (son[fa[x],2]<>x));
 29   end;
 30 
 31 procedure update(x:longint);
 32   begin
 33     w[x]:=x;
 34     if v[w[son[x,1]]]>v[w[x]] then w[x]:=w[son[x,1]];
 35     if v[w[son[x,2]]]>v[w[x]] then w[x]:=w[son[x,2]];
 36   end;
 37 
 38 procedure push(x:longint);
 39   begin
 40     if rev[x] then
 41     begin
 42       rev[son[x,1]]:=not rev[son[x,1]];
 43       rev[son[x,2]]:=not rev[son[x,2]];
 44       swap(son[x,1],son[x,2]);
 45       rev[x]:=false;
 46     end;
 47   end;
 48 
 49 procedure rotate(x,w:longint);
 50   var y:longint;
 51   begin
 52     y:=fa[x];
 53     if not root(y) then
 54     begin
 55       if son[fa[y],1]=y then son[fa[y],1]:=x
 56       else son[fa[y],2]:=x;
 57     end;
 58     fa[x]:=fa[y];
 59     son[y,3-w]:=son[x,w];
 60     if son[x,w]<>0 then fa[son[x,w]]:=y;
 61     son[x,w]:=y;
 62     fa[y]:=x;
 63     update(y);
 64   end;
 65 
 66 procedure splay(x:longint);
 67   var y,t,i:longint;
 68   begin
 69     t:=0;
 70     i:=x;
 71     while not root(i) do
 72     begin
 73       inc(t);
 74       q[t]:=i;
 75       i:=fa[i];
 76     end;
 77     inc(t);
 78     q[t]:=i;
 79     for i:=t downto 1 do
 80       push(q[i]);
 81     while not root(x) do
 82     begin
 83       y:=fa[x];
 84       if root(y) then
 85       begin
 86         if son[y,1]=x then rotate(x,2)
 87         else rotate(x,1);
 88       end
 89       else begin
 90         if son[fa[y],1]=y then
 91         begin
 92           if son[y,1]=x then rotate(y,2)
 93           else rotate(x,1);
 94           rotate(x,2);
 95         end
 96         else begin
 97           if son[y,1]=x then rotate(x,2)
 98           else rotate(y,1);
 99           rotate(x,1);
100         end;
101       end;
102     end;
103     update(x);
104   end;
105 
106 procedure access(x:longint);
107   var y:longint;
108   begin
109     y:=0;
110     repeat
111       splay(x);
112       son[x,2]:=y;
113       update(x);
114       y:=x;
115       x:=fa[x];
116     until x=0;
117   end;
118 
119 procedure sort(l,r: longint);
120   var i,j,x,y: longint;
121   begin
122     i:=l;
123     j:=r;
124     x:=a[(l+r) div 2];
125     repeat
126       while a[i]<x do inc(i);
127       while x<a[j] do dec(j);
128       if not(i>j) then
129       begin
130         swap(s[i],s[j]);
131         swap(e[i],e[j]);
132         swap(a[i],a[j]);
133         swap(b[i],b[j]);
134         inc(i);
135         j:=j-1;
136       end;
137     until i>j;
138     if l<j then sort(l,j);
139     if i<r then sort(i,r);
140   end;
141 
142 procedure makeroot(x:longint);
143   begin
144     access(x);
145     splay(x);
146     rev[x]:=not rev[x];
147   end;
148 
149 procedure path(x,y:longint);
150   begin
151     makeroot(x);
152     access(y);
153     splay(y);
154   end;
155 
156 procedure link(x,y:longint);
157   begin
158     makeroot(x);
159     fa[x]:=y;
160   end;
161 
162 procedure cut(x,y:longint);
163   begin
164     makeroot(x);
165     access(y);
166     splay(y);
167     son[y,1]:=0;
168     fa[x]:=0;
169   end;
170 
171 procedure deal(i:longint);
172   var x,y,z:longint;
173   begin
174     x:=getf(s[i]);
175     y:=getf(e[i]);
176     if x<>y then
177     begin
178       f[x]:=y;
179       link(s[i],n+i);
180       link(e[i],n+i);
181     end
182     else begin
183       x:=s[i];
184       y:=e[i];
185       path(x,y);
186       z:=w[y];
187       if v[z]>b[i] then
188       begin
189         cut(s[z-n],z);
190         cut(e[z-n],z);
191         link(s[i],n+i);
192         link(e[i],n+i);
193       end;
194     end;
195   end;
196 
197 begin
198   readln(n,m);
199   for i:=1 to m do
200     readln(s[i],e[i],a[i],b[i]);
201   for i:=1 to n do
202     f[i]:=i;
203   sort(1,m);
204   for i:=1 to m do
205   begin
206     v[n+i]:=b[i];
207     w[n+i]:=n+i;
208   end;
209   ans:=2147483647;
210   i:=0;
211   while i<m do
212   begin
213     inc(i);
214     deal(i);
215     while a[i]=a[i+1] do
216     begin
217       inc(i);
218       deal(i);
219     end;
220     if getf(1)=getf(n) then
221     begin
222       path(1,n);
223       ans:=min(ans,a[i]+v[w[n]]);
224     end;
225   end;
226   if ans=2147483647 then writeln(-1)
227   else writeln(ans);
228 end.
View Code
原文地址:https://www.cnblogs.com/phile/p/4472991.html