题目链接

戳我

\(Solution\)

两个变量,emm...不好搞啊。

于是我们可以按照\(A\)排序。然后动态加边,因为\(A\)是越来越大,所以不需要管他,只要使得\(1\)$n$的路径中$B$最大值最小。这用LCT维护生成树就好了,模板题。每次加边后满足$1$\(n\)有路径的时候将

此时最大的\(B\)+当前\(A\),去\(min\),最后输出即可

\(Code\)

  1. #include<bits/stdc++.h>
  2. #define rg register
  3. #define file(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
  4. using namespace std;
  5. int read(){
  6. int x=0,f=1;char c=getchar();
  7. while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar();
  8. while(c>='0'&&c<='9') x=x*10+c-48,c=getchar();
  9. return f*x;
  10. }
  11. struct node {
  12. int v,lazy,ch[2],fa;
  13. }a[2000001];
  14. int v[2000001],pre[2000001];
  15. int max(int x,int y){
  16. return v[x]>v[y]?x:y;
  17. }
  18. void pushup(int x){
  19. a[x].v=max(x,max(a[a[x].ch[0]].v,a[a[x].ch[1]].v));
  20. }
  21. bool nroot(int x){
  22. return a[a[x].fa].ch[0]==x||a[a[x].fa].ch[1]==x;
  23. }
  24. void work(int x){
  25. swap(a[x].ch[1],a[x].ch[0]),a[x].lazy^=1;
  26. }
  27. void pushdown(int x){
  28. if(a[x].lazy){
  29. if(a[x].ch[0]) work(a[x].ch[0]);
  30. if(a[x].ch[1]) work(a[x].ch[1]);
  31. a[x].lazy=0;
  32. }
  33. }
  34. void pushall(int x){
  35. if(nroot(x)) pushall(a[x].fa);
  36. pushdown(x);
  37. }
  38. void rotate(int x){
  39. int y=a[x].fa,z=a[y].fa,k=a[y].ch[1]==x;
  40. if(nroot(y)) a[z].ch[a[z].ch[1]==y]=x;
  41. a[x].fa=z,a[y].ch[k]=a[x].ch[k^1],a[a[x].ch[k^1]].fa=y;
  42. a[x].ch[k^1]=y,a[y].fa=x,pushup(y),pushup(x);
  43. }
  44. void splay(int x){
  45. pushall(x);
  46. while(nroot(x)){
  47. int y=a[x].fa,z=a[y].fa;
  48. if(nroot(y))
  49. (a[y].ch[1]==x)^(a[z].ch[1]==y)?rotate(x):rotate(y);
  50. rotate(x);
  51. }
  52. pushup(x);
  53. }
  54. void access(int x){
  55. for(int y=0;x;y=x,x=a[x].fa)
  56. splay(x),a[x].ch[1]=y,pushup(x);
  57. }
  58. void makeroot(int x){
  59. access(x),splay(x),work(x);
  60. }
  61. int findroot(int x){
  62. access(x),splay(x);
  63. while(a[x].ch[0]) pushdown(x),x=a[x].ch[0];
  64. splay(x);
  65. return x;
  66. }
  67. void splix(int x,int y){
  68. makeroot(x),access(y),splay(y);
  69. }
  70. void link(int x,int y){
  71. makeroot(x);
  72. if(findroot(y)!=x)
  73. a[x].fa=y;
  74. }
  75. void cut(int x,int y){
  76. makeroot(x);
  77. if(findroot(y)!=x||a[y].fa!=x||a[y].ch[0]) return;
  78. a[x].ch[1]=a[y].fa=0,pushup(x);
  79. }
  80. struct node1 {
  81. int x,y,z,v;
  82. }b[1000010];
  83. bool cmp(const node1 & a , const node1 & b ){
  84. return a.z<b.z;
  85. }
  86. int find(int x){
  87. return pre[x]==x?x:pre[x]=find(pre[x]);
  88. }
  89. int main(){
  90. int n=read(),m=read(),x,minx=2147483647;
  91. for(int i=1;i<=m;i++)
  92. b[i].x=read(),b[i].y=read(),b[i].z=read(),b[i].v=read();
  93. sort(b+1,b+1+m,cmp);
  94. for(int i=1;i<=n;i++) pre[i]=i;
  95. for(int i=1;i<=m;i++) v[i+n]=b[i].v;
  96. for(int i=1;i<=m;i++){
  97. int fx=find(b[i].x),fy=find(b[i].y);
  98. if(fx!=fy)
  99. link(b[i].x,i+n),link(b[i].y,i+n),pre[fx]=fy;
  100. else if(b[i].x!=b[i].y){
  101. splix(b[i].x,b[i].y),x=a[b[i].y].v;
  102. if(v[x]>b[i].v)
  103. cut(b[x-n].x,x),cut(b[x-n].y,x),link(b[i].x,i+n),link(b[i].y,i+n);
  104. }
  105. if(find(1)==find(n))
  106. splix(1,n),minx=min(minx,v[a[n].v]+b[i].z);
  107. }
  108. if(minx==2147483647) puts("-1"),exit(0);
  109. printf("%d",minx);
  110. return 0;
  111. }

「NOI2014」魔法森林的更多相关文章

  1. 【BZOJ3669】【Noi2014】魔法森林(Link-Cut Tree)

    [BZOJ3669][Noi2014]魔法森林(Link-Cut Tree) 题面 题目描述 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n ...

  2. 「ZJOI2016」大森林 解题报告

    「ZJOI2016」大森林 神仙题... 很显然线段树搞不了 考虑离线操作 我们只搞一颗树,从位置1一直往后移动,然后维护它的形态试试 显然操作0,1都可以拆成差分的形式,就是加入和删除 因为保证了操 ...

  3. 「NOI2014」购票 解题报告

    「NOI2014」购票 写完了后发现写的做法是假的...然后居然过了,然后就懒得管正解了. 发现需要维护凸包,动态加点,询问区间,强制在线 可以二进制分组搞,然后你发现在树上需要资瓷撤回,然后暴力撤回 ...

  4. 「NOI2014」购票

    「NOI2014」购票 解题思路 先列出 \(dp\) 式子并稍微转化一下 \[ dp[u] =\min(dp[v]+(dis[u]-dis[v]) \times p[u] + q[u])) \ \ ...

  5. BZOJ 3669 【NOI2014】 魔法森林

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

  6. 【NOI2014】魔法森林

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

  7. 【NOI2014】魔法森林 - 动态加边SPFA

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

  8. @loj - 2092@ 「ZJOI2016」大森林

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 小 Y 家里有一个大森林,里面有 n 棵树,编号从 1 到 n. ...

  9. 【BZOJ】【3669】【NOI2014】魔法森林

    LCT动态维护MST LCT动态维护MST 我们可以枚举a,然后找从1到n的一条路径使得:这条路径上的b的最大值最小.这个路径肯定在MST上……所以枚举一遍所有的边,动态维护一个关于b值的MST即可. ...

随机推荐

  1. SpringBoot Session 管理及集群管理

    1.配置session的超时时间 : 在application.prooperties中 server.session.timeout = 600       //以秒为单位,默认最少一分钟 2.配置 ...

  2. 利用TortoiseGit从Github上下载代码

    1.首先确保安装好了Git和TortoiseGit并在Github上有存放资源 2.将git上博客源文件克隆到本地,在本地创建好要存放资源的文件夹,之后在此文件内右键单击,可以看到下拉菜单中增加了To ...

  3. Best free online svn repositories

    Maybe you want to develop in a custom team environment or you usualy work on different machines (tha ...

  4. mysql 删除死锁的事务

    select * from information_schema.innodb_trxkill 953

  5. ansible模块学习

    ansible的功能: 模块化任务,调用特定的模块,完成特定的任务 基于python语言实现,由paramiko.pyyaml和jinja2三个模块构建 部署简单,agentless,ansible基 ...

  6. 解决SQL将varchar值转换为数据类型为int的列时发生语法错误

    今天遇到一个这样的错误,具体的报错情况如下 解决的方案如下. 数据库MSSQL在比较大小时,出错提示:“将 varchar 值 '24.5' 转换为数据类型为 int 的列时发生语法错!”分析数据库设 ...

  7. Mybatis之XML使用Enum枚举传递数据

    在Mybatis中,处理枚举类的TypeHandler有两个: EnumTypeHandler: 用于保存枚举名 EnumOrdinalTypeHandler: 用于保存枚举的序号. 在实际项目中,以 ...

  8. Thrift分析

    [Thrift分析] Thrift定义一套IDL(Interface Definition Language)用于描述接口,通常后缀名为.thrift,通过thrift程序把.thrift文件导出成各 ...

  9. Ssm框架常见报错

    错误1: The origin server did not find a current representation for the target resource or is not willi ...

  10. R_CNN

    https://blog.csdn.net/briblue/article/details/82012575 背景本篇论文的题目是 <Rich feature hierarchies for a ...