1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <cmath>
  5. #include <algorithm>
  6. #define maxn 150005
  7. #define maxm 100005
  8. #define pi pair<int,int>
  9. #define mp(a,b) make_pair(a,b)
  10. using namespace std;
  11.  
  12. struct note{
  13. int u,v,a,b;
  14. }wi[maxm];
  15. int n,m,ans,fa[maxn],son[maxn][],val[maxn],sm[maxn],sm_id[maxn];
  16. bool rev[maxn];
  17.  
  18. bool comp(note x,note y){
  19. if (x.a==y.a) return x.b<y.b;
  20. return x.a<y.a;
  21. }
  22.  
  23. struct date{
  24. int which(int x){
  25. return son[fa[x]][]==x;
  26. }
  27. int isroot(int x){
  28. return son[fa[x]][]!=x&&son[fa[x]][]!=x;
  29. }
  30. void update(int x){
  31. sm_id[x]=x,sm[x]=val[x];
  32. if (son[x][]&&sm[son[x][]]>sm[x]) sm[x]=sm[son[x][]],sm_id[x]=sm_id[son[x][]];
  33. if (son[x][]&&sm[son[x][]]>sm[x]) sm[x]=sm[son[x][]],sm_id[x]=sm_id[son[x][]];
  34. }
  35. void pushdown(int x){
  36. if (rev[x]){
  37. rev[x]^=,swap(son[x][],son[x][]);
  38. if (son[x][]) rev[son[x][]]^=;
  39. if (son[x][]) rev[son[x][]]^=;
  40. }
  41. }
  42. void relax(int x){
  43. if (!isroot(x)) relax(fa[x]);
  44. pushdown(x);
  45. }
  46. void rotata(int x){
  47. int y=fa[x],d=which(x),dd=which(y);
  48. if (!isroot(y)) son[fa[y]][dd]=x; fa[x]=fa[y];
  49. fa[son[x][d^]]=y,son[y][d]=son[x][d^];
  50. fa[y]=x,son[x][d^]=y;
  51. update(y);
  52. }
  53. void splay(int x){
  54. relax(x);
  55. while (!isroot(x)){
  56. if (isroot(fa[x])) rotata(x);
  57. else if (which(x)==which(fa[x])) rotata(fa[x]),rotata(x);
  58. else rotata(x),rotata(x);
  59. }
  60. update(x);
  61. }
  62. void access(int x){
  63. for (int p=;x;x=fa[x]){
  64. splay(x);
  65. son[x][]=p;
  66. update(x);
  67. p=x;
  68. }
  69. }
  70. void make_root(int x){
  71. access(x);
  72. splay(x);
  73. rev[x]^=;
  74. }
  75. void link(int x,int y){
  76. make_root(x);
  77. fa[x]=y;
  78. }
  79. void cut(int x,int y){
  80. make_root(x);
  81. access(y);
  82. splay(y);
  83. son[y][]=fa[x]=;
  84. update(y);
  85. }
  86. void split(int x,int y){
  87. make_root(x);
  88. access(y);
  89. splay(y);
  90. }
  91. int query(int x,int y){
  92. split(x,y);
  93. return sm[y];
  94. }
  95. pi find(int x,int y){
  96. split(x,y);
  97. return mp(sm_id[y],sm[y]);
  98. }
  99. int find_root(int x){
  100. access(x);
  101. splay(x);
  102. while (son[x][]) x=son[x][];
  103. return x;
  104. }
  105. }lct;
  106.  
  107. int main(){
  108. // freopen("forest.in","r",stdin);
  109. // freopen("forest.out","w",stdout);
  110. memset(rev,,sizeof(rev));
  111. memset(fa,,sizeof(fa));
  112. memset(son,,sizeof(son));
  113. memset(val,,sizeof(val));
  114. memset(sm,,sizeof(sm));
  115. scanf("%d%d",&n,&m);
  116. for (int i=;i<=m;i++) scanf("%d%d%d%d",&wi[i].u,&wi[i].v,&wi[i].a,&wi[i].b);
  117. sort(wi+,wi+m+,comp);
  118. for (int i=;i<=n;i++) val[i]=,lct.update(i);
  119. ans=maxn;
  120. pi temp;
  121. for (int i=;i<=m;i++){
  122. int u=wi[i].u,v=wi[i].v;
  123. if (lct.find_root(u)!=lct.find_root(v)){
  124. val[n+i]=wi[i].b,lct.update(n+i);
  125. lct.link(n+i,u),lct.link(n+i,v);
  126. }else{
  127. temp=lct.find(u,v);
  128. if (temp.second<=wi[i].b) continue;
  129. else{
  130. int t=temp.first;
  131. lct.cut(wi[t-n].u,t),lct.cut(wi[t-n].v,t);
  132. val[n+i]=wi[i].b,lct.update(n+i);
  133. lct.link(n+i,u),lct.link(n+i,v);
  134. }
  135. }
  136. if (lct.find_root()!=lct.find_root(n)) continue;
  137. int t=lct.query(,n);
  138. ans=min(ans,t+wi[i].a);
  139. }
  140. if (ans>maxm) printf("-1\n");
  141. else printf("%d\n",ans);
  142. return ;
  143. }

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3669

题目大意:给定一个无向图,每条边有两个权值va,vb,要求选一条从1到n的路径,满足这条路径上点的max(va)+max(vb)最小,若没有从A到B的路径,则输出-1。

做法:初看这题,暴力写法:将边按va升序排序,枚举i,此时max(va)=vi,保证max(vb)最小即可,我们可以想到kruscal,并查集集维护即可,但是瓶颈在于每次都要将1~i的边按vb升序排序,在O(n)的加入,这种做法复杂度过高,不宜使用。

仔细想想:我们可以考虑用lct维护这个过程,考虑先将边按va升序排序,然后依次加入每一条边,此时max(va)=vi,保证max(vb)最小即可,加入该边时会有两种情况:

1.不形成环,则加入这条边,若节点1与节点n联通,则用1到n链上vb最大值+vi更新答案,否则不更新答案。

2.形成环,与lct模拟kruscal的过程一样,删掉原本那条链上vb权值最大的边,并加入这条边,若节点1与节点n联通,则用1到n链上vb最大值+vi更新答案,否则不更新答案。

lct+离线处理

bzoj3669[Noi2014]魔法森林的更多相关文章

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

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

  2. [bzoj3669][Noi2014]魔法森林_LCT_并查集

    魔法森林 bzoj-3669 Noi-2014 题目大意:说不明白题意系列++……题目链接 注释:略. 想法:如果只有1个参量的话spfa.dij什么的都上来了. 两个参量的话我们考虑,想将所有的边按 ...

  3. BZOJ3669[Noi2014]魔法森林——kruskal+LCT

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

  4. BZOJ3669 [Noi2014]魔法森林(SPFA+动态加边)

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  5. BZOJ3669: [Noi2014]魔法森林(瓶颈生成树 LCT)

    Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 3558  Solved: 2283[Submit][Status][Discuss] Descript ...

  6. [bzoj3669][Noi2014]魔法森林——lct

    Brief description 给定一个无向图,求从1到n的一条路径使得这条路径上最大的a和b最小. Algorithm Design 以下内容选自某HN神犇的blog 双瓶颈的最小生成树的感觉, ...

  7. bzoj3669: [Noi2014]魔法森林 lct

    记得去年模拟赛的时候好像YY出二分答案枚举a,b的暴力,过了55欸 然后看正解,为了将两维变成一维,将a排序,模拟Kruskal的加边过程,同时维护1到n的最大值,加入一条边e(u,v,a,b)时有以 ...

  8. 沉迷Link-Cut tree无法自拔之:[BZOJ3669][Noi2014] 魔法森林

    来自蒟蒻 \(Hero \_of \_Someone\) 的 \(LCT\) 学习笔记 $ $ 有一个很好的做法是 \(spfa\) ,但是我们不聊 \(spfa\) , 来聊 \(LCT\) \(L ...

  9. BZOJ3669 NOI2014魔法森林

    按a从小到大排序,然后按b建图. 每次只需要找1~n中最大的b加当前的a计算答案即可. 这里还有一个小操作就是化边为点,把一条边的边权看做一个点的点权然后多连两条边. By:大奕哥 #include& ...

随机推荐

  1. Microsoft.Office.Interop.Excel, Version=12.0.0.0版本高于引用的程序集(已解决)

    Microsoft.Office.Interop.Excel, Version=12.0.0.0版本高于引用的程序集(已解决) 论坛里的帮助:http://bbs.csdn.net/topics/39 ...

  2. P3381 【模板】最小费用最大流

    P3381 [模板]最小费用最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入输出格式 输入格式: 第一行 ...

  3. Theano2.1.16-基础知识之调试:常见的问题解答

    来自:http://deeplearning.net/software/theano/tutorial/shape_info.html Debugging Theano: FAQ and Troubl ...

  4. canvas api

    基本骨骼 <canvas id="canvas" width=1000 height=1000 style="border: 1px black dotted&qu ...

  5. 从大公司做.NET 开发跳槽后来到小公司的做.NET移动端微信开发的个人感慨

    从14年11月的实习到正式的工作的工作我在上一家公司工作一年多了.然而到16年5月20跳槽后自己已经好久都没有在写博客了,在加上回学校毕业答辩3天以及拿档案中途耽搁了几天的时间,跳槽后虽然每天都在不停 ...

  6. Github优秀java项目集合(中文版) - 涉及java所有的知识体系

    Java资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列的资源整理.awesome-java 就是 akullpp 发起维护的 Java 资源列表,内容 ...

  7. APP架子迁移指南(一)

    搭架子是脑垂体在放烟花 俗话说吃多少饭,走多少路,上学的时候捧着<设计模式>就想睡觉,现在轮子看得多了,自然有心领神会之感.搭架子就像谈哲学,如高山流水,遇弯则急.遇潭则深.我印象最深的是 ...

  8. 提高Visual Studio开发性能的几款插件

    通过打开Visual Studio,单机TOOLS—Extensions and Updates-Online-Visual Studio Gallery(工具-扩展和更新-联网-Visual Stu ...

  9. HBase初探

    string hbaseCluster = "https://charju.azurehdinsight.net"; string hadoopUsername = "账 ...

  10. Excel导入导出(篇二)

    <body> <h3>一.Excel导入</h3> <h5>.模板下载:<a href="UpFiles/TemplateFiles/学 ...