[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) ------------------------------------------------------------------- ...
随机推荐
- js 改变this指向的三种方法 bind call apply
先了解下bind call apply 的注意点 bind 需要手动调用 第一个参数 this 要指向的对象,后面是 散列的参数 call 不需要手动调用 第一个参数 this 要指向的对象,后面是 ...
- GoLang设计模式10 - 中介者模式
中介者模式是一种行为型设计模式.在中介者模式中创建了一个中介对象来负责不同类间的通信.因为这些类不需要直接交互,所以也就能避免它们之间的直接依赖,实现解耦的效果. 中介者模式的一个典型案例是老式小火车 ...
- C语言对"不定长"字符串数组的遍历
一般来说,c语言的数组的初始化可以通过三种方式: {0},在声明时使用,如 int a[10]={0} 使用memset, memset(array,0,sizeof(array)) 用for循环赋值 ...
- python和shell 取日期为今天的行
按条件取行 todolist.txt是存储所有数据的地方,每次查看数据库显得麻烦. 在执行命令后,要在终端显示今日应作事项. 首先用linux 的shell脚本来实现该功能. grep指令可以在文件中 ...
- Dapr-服务调用
前言 上一篇对Dapr进行了了解,并搭建了Dapr环境.接下来就对Dapr的各个构建块类型的了解.应用实际案例. 一.服务调用: 在许多具有多个需要相互通信的服务的环境中,都会面临着很多问题. 如: ...
- Golang通脉之类型定义
自定义类型 在Go语言中有一些基本的数据类型,如string.整型.浮点型.布尔等数据类型, Go语言中可以使用type关键字来定义自定义类型. type是Go语法里的重要而且常用的关键字,type绝 ...
- Python语法1
变量 命名规则 变量名必须是大小写英文字母.数字或下划线 _ 的组合,不能用数字开头,并且对大小写敏感 变量赋值 同一变量可以反复赋值,而且可以是不同类型的变量 i=2; i="name&q ...
- Sequence Model-week2编程题1-词向量的操作【余弦相似度 词类比 除偏词向量】
1. 词向量上的操作(Operations on word vectors) 因为词嵌入的训练是非常耗资源的,所以ML从业者通常 都是 选择加载训练好 的 词嵌入(Embedding)数据集.(不用自 ...
- 北航OO第三单元总结
JML基础梳理及工具链 JML的全称是Java Modeling language,即Java建模语言.JML是一种行为接口规格.它为严格的程序设计提供了一套行之有效的方法.通过JML不仅可以基于规格 ...
- js基础学习之"=="与"==="的区别
var a = 1; var b = 1; var c = "1"; 1. "==" 可理解为相等运算符.相等运算符比较时,会自己进行类型转换,等于什么类型就会 ...