题意:有一张无向图,每条边有两个权值。求选取一些边使1和n连通,且max(a[i])+max(b[i])最小

2<=n<=50,000

0<=m<=100,000

1<=ai ,bi<=50,000

思路:LCT模板

将a[i]排序,维护路径上b[i]的最大值

因为是无向图且连通情况不变,不用findroot检查是否连通,并查集即可

也许是OI生涯最后一次打LCT

  1. var t:array[..,..]of longint;
  2. rev,fa,mx,w,a,b,f,q,x,y:array[..]of longint;
  3. n,m,i,j,u,v,ans,tmp,top:longint;
  4.  
  5. procedure swap(var x,y:longint);
  6. var t:longint;
  7. begin
  8. t:=x; x:=y; y:=t;
  9. end;
  10.  
  11. function min(x,y:longint):longint;
  12. begin
  13. if x<y then exit(x);
  14. exit(y);
  15. end;
  16.  
  17. function isroot(x:longint):boolean;
  18. begin
  19. if (t[fa[x],]<>x)and(t[fa[x],]<>x) then exit(true);
  20. exit(false);
  21. end;
  22.  
  23. procedure pushup(p:longint);
  24. var l,r:longint;
  25. begin
  26. l:=t[p,]; r:=t[p,];
  27. mx[p]:=p;
  28. if w[mx[l]]>w[mx[p]] then mx[p]:=mx[l];
  29. if w[mx[r]]>w[mx[p]] then mx[p]:=mx[r];
  30. end;
  31.  
  32. procedure pushdown(p:longint);
  33. var l,r:longint;
  34. begin
  35. l:=t[p,]; r:=t[p,];
  36. if rev[p]= then
  37. begin
  38. rev[p]:=; rev[l]:=rev[l] xor ; rev[r]:=rev[r] xor ;
  39. swap(t[p,],t[p,]);
  40. end;
  41. end;
  42.  
  43. procedure rotate(x:longint);
  44. var y,z,l,r:longint;
  45. begin
  46. y:=fa[x]; z:=fa[y];
  47. if t[y,]=x then l:=
  48. else l:=;
  49. r:=l xor ;
  50. if not isroot(y) then
  51. begin
  52. if t[z,]=y then t[z,]:=x
  53. else t[z,]:=x;
  54. end;
  55. fa[x]:=z; fa[y]:=x; fa[t[x,r]]:=y;
  56. t[y,l]:=t[x,r]; t[x,r]:=y;
  57. pushup(y);
  58. pushup(x);
  59. end;
  60.  
  61. procedure splay(x:longint);
  62. var y,z,k:longint;
  63. begin
  64. inc(top); q[top]:=x;
  65. k:=x;
  66. while not isroot(k) do
  67. begin
  68. inc(top); q[top]:=fa[k];
  69. k:=fa[k];
  70. end;
  71. while top> do
  72. begin
  73. pushdown(q[top]);
  74. dec(top);
  75. end;
  76.  
  77. while not isroot(x) do
  78. begin
  79. y:=fa[x]; z:=fa[y];
  80. if not isroot(y) then
  81. begin
  82. if (t[y,]=x)xor(t[z,]=y) then rotate(x)
  83. else rotate(y);
  84. end;
  85. rotate(x);
  86. end;
  87. end;
  88.  
  89. procedure access(x:longint);
  90. var k:longint;
  91. begin
  92. k:=;
  93. while x> do
  94. begin
  95. splay(x); t[x,]:=k; pushup(x);
  96. k:=x; x:=fa[x];
  97. end;
  98. end;
  99.  
  100. procedure makeroot(x:longint);
  101. begin
  102. access(x); splay(x); rev[x]:=rev[x] xor ;
  103. end;
  104.  
  105. procedure link(x,y:longint);
  106. begin
  107. makeroot(x); fa[x]:=y;
  108. end;
  109.  
  110. procedure split(x,y:longint);
  111. begin
  112. makeroot(x); access(y); splay(y);
  113. end;
  114.  
  115. procedure cut(x,y:longint);
  116. begin
  117. makeroot(x); access(y); splay(y); t[y,]:=; fa[x]:=;
  118. pushup(y);
  119. end;
  120.  
  121. function query(x,y:longint):longint;
  122. begin
  123. split(x,y);
  124. exit(mx[y]);
  125. end;
  126.  
  127. procedure qsort(l,r:longint);
  128. var i,j,mid:longint;
  129. begin
  130. i:=l; j:=r; mid:=a[(l+r)>>];
  131. repeat
  132. while mid>a[i] do inc(i);
  133. while mid<a[j] do dec(j);
  134. if i<=j then
  135. begin
  136. swap(a[i],a[j]);
  137. swap(b[i],b[j]);
  138. swap(x[i],x[j]);
  139. swap(y[i],y[j]);
  140. inc(i); dec(j);
  141. end;
  142. until i>j;
  143. if l<j then qsort(l,j);
  144. if i<r then qsort(i,r);
  145. end;
  146.  
  147. function find(k:longint):longint;
  148. begin
  149. if f[k]<>k then f[k]:=find(f[k]);
  150. exit(f[k]);
  151. end;
  152.  
  153. begin
  154. assign(input,'bzoj3669.in'); reset(input);
  155. assign(output,'bzoj3669.out'); rewrite(output);
  156. readln(n,m);
  157. for i:= to n do f[i]:=i;
  158. for i:= to m do read(x[i],y[i],a[i],b[i]);
  159. qsort(,m);
  160. ans:=maxlongint;
  161.  
  162. for i:= to m do
  163. begin
  164. u:=x[i]; v:=y[i];
  165. if find(u)=find(v) then
  166. begin
  167. tmp:=query(u,v);
  168. if w[tmp]>b[i] then
  169. begin
  170. cut(tmp,x[tmp-n]);
  171. cut(tmp,y[tmp-n]);
  172. end
  173. else
  174. begin
  175. if find()=find(n) then
  176. begin
  177. tmp:=query(,n);
  178. ans:=min(ans,w[tmp]+a[i]);
  179. end;
  180. continue;
  181. end;
  182. end
  183. else f[find(u)]:=find(v);
  184. w[i+n]:=b[i]; mx[i+n]:=i+n;
  185. link(u,i+n); link(v,i+n);
  186. if find()=find(n) then
  187. begin
  188. tmp:=query(,n);
  189. ans:=min(ans,w[tmp]+a[i]);
  190. end;
  191. end;
  192. if ans=maxlongint then writeln(-)
  193. else writeln(ans);
  194. close(input);
  195. close(output);
  196. end.

【BZOJ3669】魔法森林(LCT)的更多相关文章

  1. 【BZOJ3669】[Noi2014]魔法森林 LCT

    终于不是裸的LCT了...然而一开始一眼看上去这是kruskal..不对,题目要求1->n的路径上的每个点的两个最大权值和最小,这样便可以用LCT来维护一个最小生成路(瞎编的...),先以a为关 ...

  2. bzoj3669: [Noi2014]魔法森林 lct版

    先上题目 bzoj3669: [Noi2014]魔法森林 这道题首先每一条边都有一个a,b 我们按a从小到大排序 每次将一条路劲入队 当然这道题权在边上 所以我们将边化为点去连接他的两个端点 当然某两 ...

  3. BZOJ-3669 魔法森林 Link-Cut-Tree

    意识到背模版的重要性了,记住了原理和操作,然后手打模版残了..颓我时间...... 3669: [Noi2014]魔法森林 Time Limit: 30 Sec Memory Limit: 512 M ...

  4. BZOJ 3669: [Noi2014]魔法森林( LCT )

    排序搞掉一维, 然后就用LCT维护加边MST. O(NlogN) ------------------------------------------------------------------- ...

  5. bzoj 3669: [Noi2014] 魔法森林 LCT版

    Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...

  6. BZOJ 3669: [Noi2014]魔法森林 [LCT Kruskal | SPFA]

    题目描述 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n 个节点 m 条边的无向图,节点标号为 1,2,3,…,n,边标号为 1,2,3,…, ...

  7. bzoj 3669: [Noi2014]魔法森林 (LCT)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3669 题面: 3669: [Noi2014]魔法森林 Time Limit: 30 Sec  ...

  8. [NOI2014]魔法森林 LCT

    题面 [NOI2014]魔法森林 题解 一条路径的代价为路径上的\(max(a[i]) + max(b[i])\),因为一条边同时有$a[i], b[i]$2种权值,直接处理不好同时兼顾到,所以我们考 ...

  9. [BZOJ3669]魔法森林

    Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...

  10. P2387 [NOI2014]魔法森林 LCT维护最小生成树

    \(\color{#0066ff}{ 题目描述 }\) 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n 个节点 m 条边的无向图,节点标号为 ...

随机推荐

  1. ORACLE 如何查看存储过程的定义

    ORACLE 如何查看存储过程的定义   相关的数据字典 USER_SOURCE 用户的存储过程.函数的源代码字典 DBA_SOURCE 整个系统所有用户的存储过程.函数的源代码字典 ALL_SOUR ...

  2. windows8.1专业版 关闭ie11总是已停止工作

    该问题通常原因: 1 系统重病毒: 2 系统和安装的软件不兼容导致. 解决方案: 1 杀毒更新至最新进行杀毒,仍未解决,重新安装系统: 2 目前身边人员多数属于该情况: 1 如安装了输入法.迅雷或其它 ...

  3. [转]Oracle - 数据库的实例、表空间、用户、表之间关系

    本文转自:http://www.cnblogs.com/adforce/p/3312252.html 完整的Oracle数据库通常由两部分组成:Oracle数据库和数据库实例. 1) 数据库是一系列物 ...

  4. Android开发学习——android数据存储

    Android的存储 Android中的数据存储方式及其存储位置 SharedPrefrence存储 1). 位置           /data/data/packageName/shared_pr ...

  5. testlink 从1.8.5 升级到 1.9.8

    step1:备份原 1.8.5 的数据库.   step2:分别下载 1.9.0 / 1.9.3 / 1.9.8 的安装包.   step3:分别解压 1.9.0 / 1.9.3 / 1.9.8 成3 ...

  6. 有意思的String字符工具类

    对String的操作是Java攻城师必备的,一个优秀的攻城师是懒惰,他会把自己的一些常见的代码写成可提供拓展和复用的工具类或者工具库,这些是这些优秀工程师的法宝. 我就先从String这个基本操作开始 ...

  7. Windows之shortcut

    System key combinations CTRL+ESC: Open Start menu ALT+TAB: Switch between open programs ALT+F4: Quit ...

  8. sql server 强制关闭连接

    USE master; GO DECLARE @SQL VARCHAR(MAX); SET @SQL='' SELECT @SQL=@SQL+'; KILL '+RTRIM(SPID) FROM ma ...

  9. mysql中 for update 使用

    解释: for update是在数据库中上锁用的,可以为数据库中的行上一个排它锁.当一个事务的操作未完成时候,其他事务可以读取但是不能写入或更新.例子: 比如一张表三个字段 , id(商品id), n ...

  10. vim common usage

    vim normal模式下 1.c+i+分隔符,删除分隔符里面的内容(不删除分隔符,c+a+分隔符则包括分隔符一起删掉) 如将光标位于'%s : %d years old ' 中,此时按c+i+'   ...