不难想到从小到大穷举a,判断在携带不超过a个B型精灵的情况下最少携带多少个B型精灵
这是一个经典的问题,显然要求出最小生成树,树上1到N路径上最大的边即是答案
所以我们要动态维护一个最小生成树可以用link cut tree维护
根据最小生成树的回路性质,我们加入一条边(u,v),保留树上u-v路径上最大边和新边中小的那个
由于这里维护的是边权,我们可以把每条边当做一个点p(u,v),连接(u,v)时,即是连接(u,p)和(v,p)
然后记录下路径上最大点权的编号即可

 var son:array[..,..] of longint;
q,f,w,fa,v:array[..] of longint;
rev:array[..] of boolean;
s,e,a,b:array[..] of longint;
ans,i,n,m:longint; function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end; function getf(x:longint):longint;
begin
if f[x]<>x then f[x]:=getf(f[x]);
exit(f[x]);
end; procedure swap(var a,b:longint);
var c:longint;
begin
c:=a;
a:=b;
b:=c;
end; function root(x:longint):boolean;
begin
exit((son[fa[x],]<>x) and (son[fa[x],]<>x));
end; procedure update(x:longint);
begin
w[x]:=x;
if v[w[son[x,]]]>v[w[x]] then w[x]:=w[son[x,]];
if v[w[son[x,]]]>v[w[x]] then w[x]:=w[son[x,]];
end; procedure push(x:longint);
begin
if rev[x] then
begin
rev[son[x,]]:=not rev[son[x,]];
rev[son[x,]]:=not rev[son[x,]];
swap(son[x,],son[x,]);
rev[x]:=false;
end;
end; procedure rotate(x,w:longint);
var y:longint;
begin
y:=fa[x];
if not root(y) then
begin
if son[fa[y],]=y then son[fa[y],]:=x
else son[fa[y],]:=x;
end;
fa[x]:=fa[y];
son[y,-w]:=son[x,w];
if son[x,w]<> then fa[son[x,w]]:=y;
son[x,w]:=y;
fa[y]:=x;
update(y);
end; procedure splay(x:longint);
var y,t,i:longint;
begin
t:=;
i:=x;
while not root(i) do
begin
inc(t);
q[t]:=i;
i:=fa[i];
end;
inc(t);
q[t]:=i;
for i:=t downto do
push(q[i]);
while not root(x) do
begin
y:=fa[x];
if root(y) then
begin
if son[y,]=x then rotate(x,)
else rotate(x,);
end
else begin
if son[fa[y],]=y then
begin
if son[y,]=x then rotate(y,)
else rotate(x,);
rotate(x,);
end
else begin
if son[y,]=x then rotate(x,)
else rotate(y,);
rotate(x,);
end;
end;
end;
update(x);
end; procedure access(x:longint);
var y:longint;
begin
y:=;
repeat
splay(x);
son[x,]:=y;
update(x);
y:=x;
x:=fa[x];
until x=;
end; procedure sort(l,r: longint);
var i,j,x,y: longint;
begin
i:=l;
j:=r;
x:=a[(l+r) div ];
repeat
while a[i]<x do inc(i);
while x<a[j] do dec(j);
if not(i>j) then
begin
swap(s[i],s[j]);
swap(e[i],e[j]);
swap(a[i],a[j]);
swap(b[i],b[j]);
inc(i);
j:=j-;
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end; procedure makeroot(x:longint);
begin
access(x);
splay(x);
rev[x]:=not rev[x];
end; procedure path(x,y:longint);
begin
makeroot(x);
access(y);
splay(y);
end; procedure link(x,y:longint);
begin
makeroot(x);
fa[x]:=y;
end; procedure cut(x,y:longint);
begin
makeroot(x);
access(y);
splay(y);
son[y,]:=;
fa[x]:=;
end; procedure deal(i:longint);
var x,y,z:longint;
begin
x:=getf(s[i]);
y:=getf(e[i]);
if x<>y then
begin
f[x]:=y;
link(s[i],n+i);
link(e[i],n+i);
end
else begin
x:=s[i];
y:=e[i];
path(x,y);
z:=w[y];
if v[z]>b[i] then
begin
cut(s[z-n],z);
cut(e[z-n],z);
link(s[i],n+i);
link(e[i],n+i);
end;
end;
end; begin
readln(n,m);
for i:= to m do
readln(s[i],e[i],a[i],b[i]);
for i:= to n do
f[i]:=i;
sort(,m);
for i:= to m do
begin
v[n+i]:=b[i];
w[n+i]:=n+i;
end;
ans:=;
i:=;
while i<m do
begin
inc(i);
deal(i);
while a[i]=a[i+] do
begin
inc(i);
deal(i);
end;
if getf()=getf(n) then
begin
path(,n);
ans:=min(ans,a[i]+v[w[n]]);
end;
end;
if ans= then writeln(-)
else writeln(ans);
end.

bzoj3669的更多相关文章

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

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

  2. 【BZOJ3669】【NOI2014】魔法森林 LCT

    题目描述 给你一个\(n\)个点\(m\)条边的图,每条边有两个边权\(a,b\).请你找出从\(1\)到\(n\)一条路径,使得这条路径上边权\(a\)的最大值\(+\)边权\(b\)的最大值最小. ...

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

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

  4. 【BZOJ3669】魔法森林(LCT)

    题意:有一张无向图,每条边有两个权值.求选取一些边使1和n连通,且max(a[i])+max(b[i])最小 2<=n<=50,000 0<=m<=100,000 1<= ...

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

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

  6. 【BZOJ3669】[Noi2014]魔法森林 LCT

    终于不是裸的LCT了...然而一开始一眼看上去这是kruskal..不对,题目要求1->n的路径上的每个点的两个最大权值和最小,这样便可以用LCT来维护一个最小生成路(瞎编的...),先以a为关 ...

  7. BZOJ3669 (动态树)

    Problem 魔法森林 (NOI2014) 题目大意 给n个点,m条边的无向图,每条边有两个权值a,b. 求一条从1-->n的路径,使得这条路径上max(a)+max(b)最小.输出最小值即可 ...

  8. bzoj3669[Noi2014]魔法森林

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...

  9. BZOJ-3669 魔法森林 Link-Cut-Tree

    意识到背模版的重要性了,记住了原理和操作,然后手打模版残了..颓我时间...... 3669: [Noi2014]魔法森林 Time Limit: 30 Sec Memory Limit: 512 M ...

随机推荐

  1. hdoj1874 (优先队列+Dijkstra)

    hdoj1874 分析: 一看题目, 就是求最短路, 这道题用的是Dijkstra+优先队列.先说一下Dijkstra算法:每次扩展一个距离最短的节点, 更新与其相邻点的距离. 当所有边权都为正时, ...

  2. iOS开发——基于corelocation位置定位——工具类

    (代码工具类已写好,空闲时间整理成文档,待更新……)

  3. The Wonderful Wizard of Oz-绿野仙踪-(音频+文本)-英文版本

    Audio: http://www.booksshouldbefree.com/book/the-wonderful-wizard-of-oz Books: http://www.gutenberg. ...

  4. avconv转换视频

    提取指定stream time avconv -i i.mkv -map 0:0 -map 0:1 -map 0:5 -c:v copy -c:a:0 mp3 -c:s copy o.mkv 合并 a ...

  5. height为100%的问题

    问题描述 很多同学,对于设置div 的高度为100%时,有疑惑. 设置div 的高度为100%,意思是此 div 的高度 铺满父元素. 那么 怎么使 div 铺满浏览器屏幕? 代码 <!DOCT ...

  6. oracle所在磁盘空间不足导致了数据库异常

    oracle所在磁盘空间不足导致了数据库异常.需要减小数据文件的大小来解决. 1.检查数据文件的名称和编号 select file#,name from v$datafile; 2.看哪个数据文件所占 ...

  7. leetcode problem 32 -- Longest Valid Parentheses

    Longest Valid Parentheses Given a string containing just the characters '(' and ')', find the length ...

  8. 网站开发常用jQuery插件总结(十)菜单插件superfish

    网站对于菜单的依赖其实并不是很大,我们完全可以不使用菜单来设计网站,显示网站内容.但是如果网站的分类太多,“也许”使用菜单作为网站导航可以使 用户 更方便的寻找内容.superfish插件就是用于实现 ...

  9. HTTP协议-标签简介

    这个系列的文章要讨论的是如何通过ASP.net服务器端技术来优化客户端缓存策略,而且让这种策略变得可配置和可扩展.我们要了解的知识从HTTP协议中相关属性对客户端缓存的影响,到ASP.NET如何控制这 ...

  10. HTML 表单和表格

    1.使用表单标签 网站使用 HTML 表单可与用户进行交互,表单元素是允许用户在表单中输入内容,比如:文本框.文本域.单选框.复选框.下拉列表.按钮等等,表单可以把浏览者输入的数据传送到服务器端,这样 ...