【题目链接】

http://www.lydsy.com/JudgeOnline/problem.php?id=3669

【题意】

给定一个无向图,求1-n的路径中最小的max{ai}+max{bi}

【思路】

将边按照a排序。LCT维护关于b的最小生成树。

顺序枚举每条边u,v,如果u,v已经连接则比较u,v路径上的最大边与新边,否则直接相连。

如果1与n连通,则用e.a+max{e.b}更新ans。直观地看,最小生成树上的max{e.b}是1..i条边加入后能够得到的最小b。

_max的初值赋-1,即保证maxe存在,否则无限TLE

【代码】

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<algorithm>
  5. #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
  6. using namespace std;
  7.  
  8. typedef long long ll;
  9. const int N = 1e5+;
  10.  
  11. ll read() {
  12. char c=getchar();
  13. ll f=,x=;
  14. while(!isdigit(c)) {
  15. if(c=='-') f=-; c=getchar();
  16. }
  17. while(isdigit(c))
  18. x=x*+c-'',c=getchar();
  19. return x*f;
  20. }
  21.  
  22. struct Edge {
  23. int u,v,a,b;
  24. bool operator < (const Edge& rhs) const {
  25. return a<rhs.a;
  26. }
  27. }e[N<<];
  28. int en;
  29. void adde(int u,int v,int a,int b)
  30. {
  31. e[++en]=(Edge){u,v,a,b};
  32. }
  33.  
  34. namespace LCT {
  35.  
  36. struct Node {
  37. int rev,v,maxe;
  38. Node *ch[],*fa;
  39. Node() {}
  40. Node(int x) ;
  41. void reverse() {
  42. rev^=;
  43. swap(ch[],ch[]);
  44. }
  45. void up_push() {
  46. if(fa->ch[]==this||fa->ch[]==this)
  47. fa->up_push();
  48. if(rev) {
  49. ch[]->reverse();
  50. ch[]->reverse();
  51. rev=;
  52. }
  53. }
  54. void maintain() {
  55. int _max=-;
  56. if(e[ch[]->maxe].b>_max)
  57. _max=e[ch[]->maxe].b,maxe=ch[]->maxe;
  58. if(e[ch[]->maxe].b>_max)
  59. _max=e[ch[]->maxe].b,maxe=ch[]->maxe;
  60. if(e[v].b>_max) maxe=v;
  61. }
  62. } T[N<<],E[N<<],*null=&T[];
  63. Node::Node(int x) {
  64. ch[]=ch[]=fa=null;
  65. rev=; v=maxe=x;
  66. }
  67.  
  68. void rot(Node* o,int d) {
  69. Node *p=o->fa;
  70. p->ch[d]=o->ch[d^];
  71. o->ch[d^]->fa=p;
  72. o->ch[d^]=p;
  73. o->fa=p->fa;
  74. if(p==p->fa->ch[])
  75. p->fa->ch[]=o;
  76. else if(p==p->fa->ch[])
  77. p->fa->ch[]=o;
  78. p->fa=o;
  79. p->maintain();
  80. }
  81. void splay(Node* o) {
  82. o->up_push();
  83. Node* nf,*nff;
  84. while(o->fa->ch[]==o||o->fa->ch[]==o) {
  85. nf=o->fa,nff=nf->fa;
  86. if(o==nf->ch[]) {
  87. if(nf==nff->ch[]) rot(nf,);
  88. rot(o,);
  89. } else {
  90. if(nf==nff->ch[]) rot(nf,);
  91. rot(o,);
  92. }
  93. }
  94. o->maintain();
  95. }
  96. void Access(Node *o) {
  97. Node *son=null;
  98. while(o!=null) {
  99. splay(o);
  100. o->ch[]=son;
  101. o->maintain();
  102. son=o; o=o->fa;
  103. }
  104. }
  105. void evert(Node *o) {
  106. Access(o);
  107. splay(o);
  108. o->reverse();
  109. }
  110. void Link(Node *u,Node *v) {
  111. evert(u);
  112. u->fa=v;
  113. }
  114. void Cut(Node *u,Node *v) {
  115. evert(u);
  116. Access(v),splay(v);
  117. v->ch[]=u->fa=null;
  118. v->maintain();
  119. }
  120. Node *find(Node *o) {
  121. while(o->fa!=null) o=o->fa;
  122. return o;
  123. }
  124.  
  125. }
  126. using namespace LCT ;
  127.  
  128. int n,m;
  129.  
  130. int query(Node *u,Node* v)
  131. {
  132. evert(u);
  133. Access(v),splay(v);
  134. return v->maxe;
  135. }
  136.  
  137. int main()
  138. {
  139. // freopen("in.in","r",stdin);
  140. // freopen("out.out","w",stdout);
  141. n=read(),m=read();
  142. int u,v,a,b;
  143. FOR(i,,m) {
  144. u=read(),v=read(),a=read(),b=read();
  145. adde(u,v,a,b);
  146. }
  147. FOR(i,,m) E[i]=Node(i);
  148. FOR(i,,n) T[i]=Node();
  149. sort(e+,e+m+);
  150. int ans=1e9;
  151. FOR(i,,m) {
  152. int u=e[i].u,v=e[i].v;
  153. if(find(&T[u])==find(&T[v])) {
  154. int maxe=query(&T[u],&T[v]);
  155. if(e[i].b>=e[maxe].b) continue;
  156. Cut(&E[maxe],&T[e[maxe].u]);
  157. Cut(&E[maxe],&T[e[maxe].v]);
  158. }
  159. Link(&T[u],&E[i]);
  160. Link(&T[v],&E[i]);
  161. if(find(&T[])==find(&T[n])) {
  162. int maxe=query(&T[],&T[n]);
  163. if(e[maxe].b+e[i].a<ans) ans=e[maxe].b+e[i].a;
  164. }
  165. }
  166. if(ans==1e9) puts("-1");
  167. else printf("%d\n",ans);
  168. return ;
  169. }

3669 [Noi2014]魔法森林(LCT,最小生成树)的更多相关文章

  1. BZOJ 3669: [Noi2014]魔法森林(lct+最小生成树)

    传送门 解题思路 \(lct\)维护最小生成树.我们首先按照\(a\)排序,然后每次加入一条边,在图中维护一棵最小生成树.用并查集判断一下\(1\)与\(n\)是否联通,如果联通的话就尝试更新答案. ...

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

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

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

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

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

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

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

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

  6. bzoj 3669: [Noi2014]魔法森林

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

  7. bzoj 3669: [Noi2014]魔法森林 动态树

    3669: [Noi2014]魔法森林 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 363  Solved: 202[Submit][Status] ...

  8. bzoj 3669: [Noi2014]魔法森林 -- 动点spfa

    3669: [Noi2014]魔法森林 Time Limit: 30 Sec  Memory Limit: 512 MB 动点spfa Description 为了得到书法大家的真传,小E同学下定决心 ...

  9. 【BZOJ 3669】 3669: [Noi2014]魔法森林 (动态spfa)

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

  10. [NOI2014]魔法森林 LCT

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

随机推荐

  1. python3.0与2.x之间的区别

    python3.0与2.x之间的区别: 1.性能 Py3.0运行pystone benchmark的速度比Py2.5慢30%.Guido认为Py3.0有极大的优化空间,在字符串和整形操作上可以取得很好 ...

  2. iOS开发--数组

    1.sortedArrayUsingSelector (按Key值大小对NSDictionary排序) NSMutableArray *array = [NSMutableArray arrayWit ...

  3. 用Eclipse编写运行Java程序

    1.选择一个空的文件夹,作为workspace工作空间,用来存放你以后用eclipse写的Java程序.(一个workspace可以放很多很多project项目) 2.新建java项目:File-&g ...

  4. java获取当前操作系统的信息

    java获取当前操作系统的信息 JavaOS虚拟机UnixEXT  从网上收集的一些关于java获取操作系统信息的方法,现在总结一下: 1获取本机的IP地址: private static Strin ...

  5. RESTful WebService入门

    RESTful WebService入门   RESTful WebService是比基于SOAP消息的WebService简单的多的一种轻量级Web服务,RESTful WebService是没有状 ...

  6. C++:虚函数的引入

    5.4虚函数5.4.1 虚函数的引入 //例5.19 虚函数的引例 #include<iostream> using namespace std; class MyBase{ //声明基类 ...

  7. Android如何获取开机启动项列表

    static final String BOOT_START_PERMISSION = "android.permission.RECEIVE_BOOT_COMPLETED"; p ...

  8. Bean不同配置方式比较

      基于XML配置 基于注解配置 基于Java类配置 Bean定义 在XML文件中通过<bean>元素定义Bean,如:<bean class="com.bbt.UserD ...

  9. 【POJ】3523 The Morning after Halloween

    1. 题目描述$m \times n$的迷宫(最大为$16 \times 16$)包含最多3个点,这些点可以同时向相邻方向移动或保持停止,使用小写字母表示起始位置,使用大写字母表示中止位置.求最少经过 ...

  10. Base64 Encoding / Decoding in Node.js

    Posted on April 20th, 2012 under Node.js Tags: ASCII, Buffer, Encoding, node.js, UTF So how do you e ...