[loj2245]魔法森林
枚举携带的"A型守护精灵"数$A_{0}$,那么即只能经过$A_{i}\le A_{0}$的边,并最小化1到$n$路径上最大的$B_{i}$
将所有边按照$A_{i}$从小到大排序,那么前者即不断加入边,后者通过LCT维护$B_{i}$的最小生成树即可
具体的,将每一条边拆成一个点,向对应的两端点连边,加入一条边时查询对应环(若不产生环则直接加入)上$B_{i}$最大的边并替换即可
时间复杂度为$o(m\log m)$,可以通过

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 150005
4 struct Data{
5 int x,y,a,b;
6 bool operator < (const Data &k)const{
7 return a<k.a;
8 }
9 }e[N];
10 multiset<int>S;
11 int n,m,ans,st[N],fa[N],sz[N],rev[N],val[N],mx[N],ch[N][2];
12 int which(int k){
13 return ch[fa[k]][1]==k;
14 }
15 int check(int k){
16 return ch[fa[k]][which(k)]==k;
17 }
18 int get_max(int x,int y){
19 if (e[x].b>e[y].b)return x;
20 return y;
21 }
22 void upd(int k){
23 rev[k]^=1;
24 swap(ch[k][0],ch[k][1]);
25 }
26 void up(int k){
27 sz[k]=sz[ch[k][0]]+sz[ch[k][1]]+1;
28 mx[k]=get_max(get_max(mx[ch[k][0]],mx[ch[k][1]]),val[k]);
29 }
30 void down(int k){
31 if (rev[k]){
32 if (ch[k][0])upd(ch[k][0]);
33 if (ch[k][1])upd(ch[k][1]);
34 rev[k]=0;
35 }
36 }
37 void rotate(int k){
38 int f=fa[k],g=fa[f],p=which(k);
39 fa[k]=g;
40 if (check(f))ch[g][which(f)]=k;
41 fa[ch[k][p^1]]=f,ch[f][p]=ch[k][p^1];
42 fa[f]=k,ch[k][p^1]=f;
43 up(f),up(k);
44 }
45 void splay(int k){
46 for(int i=k;;i=fa[i]){
47 st[++st[0]]=i;
48 if (!check(i))break;
49 }
50 while (st[0])down(st[st[0]--]);
51 for(int i=fa[k];check(k);i=fa[k]){
52 if (check(i)){
53 if (which(i)==which(k))rotate(i);
54 else rotate(k);
55 }
56 rotate(k);
57 }
58 }
59 void access(int k){
60 int lst=0;
61 while (k){
62 splay(k);
63 ch[k][1]=lst,up(k);
64 lst=k,k=fa[k];
65 }
66 }
67 void make_root(int k){
68 access(k);
69 splay(k);
70 upd(k);
71 }
72 int find_root(int k){
73 access(k);
74 splay(k);
75 while (ch[k][0]){
76 down(k);
77 k=ch[k][0];
78 }
79 splay(k);
80 return k;
81 }
82 void add(int x,int y){
83 make_root(x);
84 make_root(y);
85 fa[y]=x;
86 }
87 void del(int x,int y){
88 make_root(x);
89 access(y);
90 splay(x);
91 fa[y]=ch[x][1]=0;
92 up(x);
93 }
94 int query(int x,int y){
95 make_root(x);
96 if (find_root(y)!=x)return -1;
97 return mx[x];
98 }
99 int main(){
100 scanf("%d%d",&n,&m);
101 for(int i=1;i<=m;i++)scanf("%d%d%d%d",&e[i].x,&e[i].y,&e[i].a,&e[i].b);
102 sort(e+1,e+m+1);
103 for(int i=1;i<=m;i++)val[i+n]=mx[i+n]=i;
104 for(int i=1;i<=m;i++)add(e[i].x,i+n);
105 ans=1e9;
106 for(int i=1;i<=m;i++){
107 int s=query(e[i].y,i+n);
108 if (s!=i){
109 if (s>0)del(e[s].y,s+n);
110 add(e[i].y,i+n);
111 }
112 s=query(1,n);
113 if (s>0)ans=min(ans,e[i].a+e[s].b);
114 }
115 if (ans==1e9)ans=-1;
116 printf("%d\n",ans);
117 return 0;
118 }
[loj2245]魔法森林的更多相关文章
- loj2245 [NOI2014]魔法森林 LCT
[NOI2014]魔法森林 链接 loj 思路 a排序,b做动态最小生成树. 把边拆成点就可以了. uoj98.也许lct复杂度写假了..越卡常,越慢 代码 #include <bits/std ...
- 【BZOJ3669】[Noi2014]魔法森林 LCT
终于不是裸的LCT了...然而一开始一眼看上去这是kruskal..不对,题目要求1->n的路径上的每个点的两个最大权值和最小,这样便可以用LCT来维护一个最小生成路(瞎编的...),先以a为关 ...
- BZOJ 3669 【NOI2014】 魔法森林
Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...
- BZOJ-3669 魔法森林 Link-Cut-Tree
意识到背模版的重要性了,记住了原理和操作,然后手打模版残了..颓我时间...... 3669: [Noi2014]魔法森林 Time Limit: 30 Sec Memory Limit: 512 M ...
- 【BZOJ】3669: [Noi2014]魔法森林(lct+特殊的技巧)
http://www.lydsy.com/JudgeOnline/problem.php?id=3669 首先看到题目应该可以得到我们要最小化 min{ max{a(u, v)} + max{b(u, ...
- NOI2014 魔法森林
3669: [Noi2014]魔法森林 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 106 Solved: 62[Submit][Status] ...
- bzoj 3669: [Noi2014]魔法森林 动态树
3669: [Noi2014]魔法森林 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 363 Solved: 202[Submit][Status] ...
- 图论 BZOJ 3669 [Noi2014]魔法森林
Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...
- BZOJ 3669: [Noi2014]魔法森林( LCT )
排序搞掉一维, 然后就用LCT维护加边MST. O(NlogN) ------------------------------------------------------------------- ...
随机推荐
- JDK源码阅读(3):AbstractStringBuilder、StringBuffer、StringBuilder类阅读笔记
AbstractStringBuilder abstract class AbstractStringBuilder implements Appendable, CharSequence{ ... ...
- VS2013的主函数问题
报错如下: 打开属性里面,修改字符集即可
- C++核心编程 1 程序的内存模型
1.内存分区模型 C++程序在执行时,将内存大方向划分为4个区域 代码区:存放函数体的二进制代码,由操作系统进行管理(写的所有代码都在代码区) 全局区:存放全局变量.静态变量以及常量 栈 区:由编 ...
- Rigidbody钢体移动时抖动问题
Rigidbody移动时抖动问题 撞墙抖动 Unity中物体移动有非常多的方式: 比如: transform.position += dir*speed*Time.deltaTime; transfo ...
- appium操作安卓应用所需要的数据准备
操作系统.系统版本如下所示: desired_caps={} desired_caps["platformName"]="Android" desired_ca ...
- SpringCloud 2020.0.4 系列之Eureka
1. 概述 老话说的好:遇见困难,首先要做的是积极的想解决办法,而不是先去泄气.抱怨或生气. 言归正传,微服务是当今非常流行的一种架构方式,其中 SpringCloud 是我们常用的一种微服务框架. ...
- (课内)信安数基RSA-level1&&2
注:(不求甚解的)攻击原理 以及(浅层的)算法解释已在图片中给出:文字部分主要讲一些python语法的东西. 代码需要库 gmpy2和libnum:加密算法还需要Crypto.Util.number ...
- 【UE4 C++ 基础知识】<13> 多线程——TaskGraph
概述 TaskGraph 系统是UE4一套抽象的异步任务处理系统 TaskGraph 可以看作一种"基于任务的并行编程"设计思想下的实现 通过TaskGraph ,可以创建任意多线 ...
- 【二食堂】Beta - 事后分析
事后分析 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? Beta阶段我们首先要对文本标注方式进行优化,其次时添加好友系统,实现邀请好友共同标注的功能. ...
- 第5次 Beta Scrum Meeting
本次会议为Beta阶段第6次Scrum Meeting会议 会议概要 会议时间:2021年6月6日 会议地点:「腾讯会议」线上进行 会议时长:10min 会议内容简介:对完成工作进行阶段性汇报:对下一 ...