【BZOJ3669】魔法森林(LCT)
题意:有一张无向图,每条边有两个权值。求选取一些边使1和n连通,且max(a[i])+max(b[i])最小
2<=n<=50,000
0<=m<=100,000
1<=ai ,bi<=50,000
思路:LCT模板
将a[i]排序,维护路径上b[i]的最大值
因为是无向图且连通情况不变,不用findroot检查是否连通,并查集即可
也许是OI生涯最后一次打LCT
- var t:array[..,..]of longint;
- rev,fa,mx,w,a,b,f,q,x,y:array[..]of longint;
- n,m,i,j,u,v,ans,tmp,top:longint;
- procedure swap(var x,y:longint);
- var t:longint;
- begin
- t:=x; x:=y; y:=t;
- end;
- function min(x,y:longint):longint;
- begin
- if x<y then exit(x);
- exit(y);
- end;
- function isroot(x:longint):boolean;
- begin
- if (t[fa[x],]<>x)and(t[fa[x],]<>x) then exit(true);
- exit(false);
- end;
- procedure pushup(p:longint);
- var l,r:longint;
- begin
- l:=t[p,]; r:=t[p,];
- mx[p]:=p;
- if w[mx[l]]>w[mx[p]] then mx[p]:=mx[l];
- if w[mx[r]]>w[mx[p]] then mx[p]:=mx[r];
- end;
- procedure pushdown(p:longint);
- var l,r:longint;
- begin
- l:=t[p,]; r:=t[p,];
- if rev[p]= then
- begin
- rev[p]:=; rev[l]:=rev[l] xor ; rev[r]:=rev[r] xor ;
- swap(t[p,],t[p,]);
- end;
- end;
- procedure rotate(x:longint);
- var y,z,l,r:longint;
- begin
- y:=fa[x]; z:=fa[y];
- if t[y,]=x then l:=
- else l:=;
- r:=l xor ;
- if not isroot(y) then
- begin
- if t[z,]=y then t[z,]:=x
- else t[z,]:=x;
- end;
- fa[x]:=z; fa[y]:=x; fa[t[x,r]]:=y;
- t[y,l]:=t[x,r]; t[x,r]:=y;
- pushup(y);
- pushup(x);
- end;
- procedure splay(x:longint);
- var y,z,k:longint;
- begin
- inc(top); q[top]:=x;
- k:=x;
- while not isroot(k) do
- begin
- inc(top); q[top]:=fa[k];
- k:=fa[k];
- end;
- while top> do
- begin
- pushdown(q[top]);
- dec(top);
- end;
- while not isroot(x) do
- begin
- y:=fa[x]; z:=fa[y];
- if not isroot(y) then
- begin
- if (t[y,]=x)xor(t[z,]=y) then rotate(x)
- else rotate(y);
- end;
- rotate(x);
- end;
- end;
- procedure access(x:longint);
- var k:longint;
- begin
- k:=;
- while x> do
- begin
- splay(x); t[x,]:=k; pushup(x);
- k:=x; x:=fa[x];
- end;
- end;
- procedure makeroot(x:longint);
- begin
- access(x); splay(x); rev[x]:=rev[x] xor ;
- end;
- procedure link(x,y:longint);
- begin
- makeroot(x); fa[x]:=y;
- end;
- procedure split(x,y:longint);
- begin
- makeroot(x); access(y); splay(y);
- end;
- procedure cut(x,y:longint);
- begin
- makeroot(x); access(y); splay(y); t[y,]:=; fa[x]:=;
- pushup(y);
- end;
- function query(x,y:longint):longint;
- begin
- split(x,y);
- exit(mx[y]);
- end;
- procedure qsort(l,r:longint);
- var i,j,mid:longint;
- begin
- i:=l; j:=r; mid:=a[(l+r)>>];
- repeat
- while mid>a[i] do inc(i);
- while mid<a[j] do dec(j);
- if i<=j then
- begin
- swap(a[i],a[j]);
- swap(b[i],b[j]);
- swap(x[i],x[j]);
- swap(y[i],y[j]);
- inc(i); dec(j);
- end;
- until i>j;
- if l<j then qsort(l,j);
- if i<r then qsort(i,r);
- end;
- function find(k:longint):longint;
- begin
- if f[k]<>k then f[k]:=find(f[k]);
- exit(f[k]);
- end;
- begin
- assign(input,'bzoj3669.in'); reset(input);
- assign(output,'bzoj3669.out'); rewrite(output);
- readln(n,m);
- for i:= to n do f[i]:=i;
- for i:= to m do read(x[i],y[i],a[i],b[i]);
- qsort(,m);
- ans:=maxlongint;
- for i:= to m do
- begin
- u:=x[i]; v:=y[i];
- if find(u)=find(v) then
- begin
- tmp:=query(u,v);
- if w[tmp]>b[i] then
- begin
- cut(tmp,x[tmp-n]);
- cut(tmp,y[tmp-n]);
- end
- else
- begin
- if find()=find(n) then
- begin
- tmp:=query(,n);
- ans:=min(ans,w[tmp]+a[i]);
- end;
- continue;
- end;
- end
- else f[find(u)]:=find(v);
- w[i+n]:=b[i]; mx[i+n]:=i+n;
- link(u,i+n); link(v,i+n);
- if find()=find(n) then
- begin
- tmp:=query(,n);
- ans:=min(ans,w[tmp]+a[i]);
- end;
- end;
- if ans=maxlongint then writeln(-)
- else writeln(ans);
- close(input);
- close(output);
- end.
【BZOJ3669】魔法森林(LCT)的更多相关文章
- 【BZOJ3669】[Noi2014]魔法森林 LCT
终于不是裸的LCT了...然而一开始一眼看上去这是kruskal..不对,题目要求1->n的路径上的每个点的两个最大权值和最小,这样便可以用LCT来维护一个最小生成路(瞎编的...),先以a为关 ...
- bzoj3669: [Noi2014]魔法森林 lct版
先上题目 bzoj3669: [Noi2014]魔法森林 这道题首先每一条边都有一个a,b 我们按a从小到大排序 每次将一条路劲入队 当然这道题权在边上 所以我们将边化为点去连接他的两个端点 当然某两 ...
- BZOJ-3669 魔法森林 Link-Cut-Tree
意识到背模版的重要性了,记住了原理和操作,然后手打模版残了..颓我时间...... 3669: [Noi2014]魔法森林 Time Limit: 30 Sec Memory Limit: 512 M ...
- BZOJ 3669: [Noi2014]魔法森林( LCT )
排序搞掉一维, 然后就用LCT维护加边MST. O(NlogN) ------------------------------------------------------------------- ...
- bzoj 3669: [Noi2014] 魔法森林 LCT版
Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...
- BZOJ 3669: [Noi2014]魔法森林 [LCT Kruskal | SPFA]
题目描述 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n 个节点 m 条边的无向图,节点标号为 1,2,3,…,n,边标号为 1,2,3,…, ...
- bzoj 3669: [Noi2014]魔法森林 (LCT)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3669 题面: 3669: [Noi2014]魔法森林 Time Limit: 30 Sec ...
- [NOI2014]魔法森林 LCT
题面 [NOI2014]魔法森林 题解 一条路径的代价为路径上的\(max(a[i]) + max(b[i])\),因为一条边同时有$a[i], b[i]$2种权值,直接处理不好同时兼顾到,所以我们考 ...
- [BZOJ3669]魔法森林
Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...
- P2387 [NOI2014]魔法森林 LCT维护最小生成树
\(\color{#0066ff}{ 题目描述 }\) 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n 个节点 m 条边的无向图,节点标号为 ...
随机推荐
- ORACLE 如何查看存储过程的定义
ORACLE 如何查看存储过程的定义 相关的数据字典 USER_SOURCE 用户的存储过程.函数的源代码字典 DBA_SOURCE 整个系统所有用户的存储过程.函数的源代码字典 ALL_SOUR ...
- windows8.1专业版 关闭ie11总是已停止工作
该问题通常原因: 1 系统重病毒: 2 系统和安装的软件不兼容导致. 解决方案: 1 杀毒更新至最新进行杀毒,仍未解决,重新安装系统: 2 目前身边人员多数属于该情况: 1 如安装了输入法.迅雷或其它 ...
- [转]Oracle - 数据库的实例、表空间、用户、表之间关系
本文转自:http://www.cnblogs.com/adforce/p/3312252.html 完整的Oracle数据库通常由两部分组成:Oracle数据库和数据库实例. 1) 数据库是一系列物 ...
- Android开发学习——android数据存储
Android的存储 Android中的数据存储方式及其存储位置 SharedPrefrence存储 1). 位置 /data/data/packageName/shared_pr ...
- testlink 从1.8.5 升级到 1.9.8
step1:备份原 1.8.5 的数据库. step2:分别下载 1.9.0 / 1.9.3 / 1.9.8 的安装包. step3:分别解压 1.9.0 / 1.9.3 / 1.9.8 成3 ...
- 有意思的String字符工具类
对String的操作是Java攻城师必备的,一个优秀的攻城师是懒惰,他会把自己的一些常见的代码写成可提供拓展和复用的工具类或者工具库,这些是这些优秀工程师的法宝. 我就先从String这个基本操作开始 ...
- Windows之shortcut
System key combinations CTRL+ESC: Open Start menu ALT+TAB: Switch between open programs ALT+F4: Quit ...
- sql server 强制关闭连接
USE master; GO DECLARE @SQL VARCHAR(MAX); SET @SQL='' SELECT @SQL=@SQL+'; KILL '+RTRIM(SPID) FROM ma ...
- mysql中 for update 使用
解释: for update是在数据库中上锁用的,可以为数据库中的行上一个排它锁.当一个事务的操作未完成时候,其他事务可以读取但是不能写入或更新.例子: 比如一张表三个字段 , id(商品id), n ...
- vim common usage
vim normal模式下 1.c+i+分隔符,删除分隔符里面的内容(不删除分隔符,c+a+分隔符则包括分隔符一起删掉) 如将光标位于'%s : %d years old ' 中,此时按c+i+' ...