【BZOJ】【3669】【NOI2014】魔法森林
LCT动态维护MST
LCT动态维护MST
我们可以枚举a,然后找从1到n的一条路径使得:这条路径上的b的最大值最小。这个路径肯定在MST上……所以枚举一遍所有的边,动态维护一个关于b值的MST即可。
调了半天没出解的原因:
rotate写错了……l=c[y][1]==x 我写成了 l=c[z][1]==y sigh……
/**************************************************************
Problem: 3669
User: Tunix
Language: C++
Result: Accepted
Time:4752 ms
Memory:7896 kb
****************************************************************/ //BZOJ 3669
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
using namespace std;
int getint(){
int v=,sign=; char ch=getchar();
while(ch<''||ch>''){ if (ch=='-') sign=-; ch=getchar();}
while(ch>=''&&ch<=''){ v=v*+ch-''; ch=getchar();}
return v*=sign;
}
const int N=,INF=~0u>>;
/******************tamplate*********************/
struct LCT{
int c[N][],fa[N],v[N],mx[N];
bool rev[N];
int st[N],top;
#define L c[x][0]
#define R c[x][1]
void Push_up(int x){
mx[x]=x;
if (v[mx[L]]>v[mx[x]]) mx[x]=mx[L];
if (v[mx[R]]>v[mx[x]]) mx[x]=mx[R];
}
void Push_down(int x){
if (rev[x]) rev[x]=,rev[L]^=,rev[R]^=,swap(L,R);
}
bool not_root(int x){
return c[fa[x]][]==x || c[fa[x]][]==x;
}
void rotate(int x){
int y=fa[x],z=fa[y],l=c[y][]==x,r=l^;
if (not_root(y)) c[z][c[z][]==y]=x;
fa[x]=z; fa[y]=x; fa[c[x][r]]=y;
c[y][l]=c[x][r]; c[x][r]=y;
Push_up(y);
}
void preview(int x){
top=; st[++top]=x;
for(;not_root(x);x=fa[x])
st[++top]=fa[x];
D(i,top,) Push_down(st[i]);
}
void splay(int x,int y=){
for(preview(x);not_root(x);rotate(x))
if (not_root(y=fa[x]))
rotate( c[y][]==x^c[fa[y]][]==y ? x : y);
Push_up(x);
}
void access(int x,int y=){
for(;x;splay(x),c[x][]=y,y=x,x=fa[x]);
}
void makeroot(int x){
access(x); splay(x); rev[x]^=;
}
void link(int x,int y){
makeroot(x);fa[x]=y;
}
void cut(int x,int y){
makeroot(x);access(y);splay(y);
if (c[y][]==x) c[y][]=fa[x]=;
}
int query(int x,int y){
makeroot(x),access(y),splay(y);
return mx[y];
}
}t;
/*********************LCT***********************/
struct edge{
int x,y,a,b;
bool operator < (const edge &e) const {
return a < e.a;
}
}e[N];
int fa[N];
int find(int x){return fa[x]==x ? x : fa[x]=find(fa[x]);} int main(){
#ifndef ONLINE_JUDGE
freopen("3669.in","r",stdin);
freopen("3669.out","w",stdout);
#endif
int n,m;
n=getint(); m=getint();
F(i,,m){
e[i].x=getint(); e[i].y=getint();
e[i].a=getint(); e[i].b=getint();
}
sort(e+,e+m+);
F(i,,m){
t.v[n+i]=e[i].b;
t.mx[n+i]=n+i;
}
F(i,,n) fa[i]=i; int ans=INF;
F(i,,m){
int f1=find(e[i].x),f2=find(e[i].y);
if (f1!=f2){
fa[f1]=f2;
t.link(e[i].x,n+i); t.link(e[i].y,n+i);
}
else{
int tmp=t.query(e[i].x,e[i].y);
if (e[i].b<t.v[tmp]){//这一步即可略去自环
t.cut(e[tmp-n].x,tmp); t.cut(e[tmp-n].y,tmp);
t.link(e[i].x,i+n); t.link(e[i].y,i+n);
}
}
f1=find(); f2=find(n);
if (f1==f2)
ans=min(ans,e[i].a+t.v[t.query(,n)]);
}
printf("%d\n",ans==INF ? - : ans);
return ;
}
【BZOJ】【3669】【NOI2014】魔法森林的更多相关文章
- bzoj 3669: [Noi2014]魔法森林
bzoj 3669: [Noi2014]魔法森林 Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号 ...
- bzoj 3669: [Noi2014]魔法森林 动态树
3669: [Noi2014]魔法森林 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 363 Solved: 202[Submit][Status] ...
- BZOJ 3669: [Noi2014]魔法森林( LCT )
排序搞掉一维, 然后就用LCT维护加边MST. O(NlogN) ------------------------------------------------------------------- ...
- bzoj 3669: [Noi2014]魔法森林 (LCT)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3669 题面: 3669: [Noi2014]魔法森林 Time Limit: 30 Sec ...
- bzoj 3669: [Noi2014]魔法森林 -- 动点spfa
3669: [Noi2014]魔法森林 Time Limit: 30 Sec Memory Limit: 512 MB 动点spfa Description 为了得到书法大家的真传,小E同学下定决心 ...
- [BZOJ 3669] [Noi2014] 魔法森林 【LCT】
题目链接:BZOJ - 3669 题目分析 如果确定了带 x 只精灵A,那么我们就是要找一条 1 到 n 的路径,满足只经过 Ai <= x 的边,而且要使经过的边中最大的 Bi 尽量小. 其实 ...
- 图论 BZOJ 3669 [Noi2014]魔法森林
Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...
- 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]魔法森林
Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...
随机推荐
- AMQ学习笔记 - 14. 实践方案:基于ZooKeeper + ActiveMQ + replicatedLevelDB的主从部署
概述 基于ZooKeeper + ActiveMQ + replicatedLevelDB,在Windows平台的主从部署方案. 主从部署可以提供数据备份.容错[1]的功能,但是不能提供负载均衡的功能 ...
- 标识域 Identify Field
在对象中保存DB的ID字段,以维持内存对象和DB数据Row之间的identify. 关系DB使用key来区分数据行. 而内存对象不需要这样的键.因为对象系统能够保证身份确认. 读取时没有问题,但是为了 ...
- node笔记——gulp修改静态文件的名字
cmd小技巧: 1.换到下级或同等级目录 D: 2.换到上级目录 cd.. node 包管理器小技巧[以gulp为例] npm install --save-dev gulp gulp-concat ...
- windows phone 8 开发系列(二)Hello Wp8!
上篇我们了解了WP8的环境搭建,从今天开始,我们就正式进入WP8的设计,开发阶段. 一. 项目模板介绍 打开vs,选择Windows Phone的项目模板,我们发现如下有很多模板,那么我们就从认识这些 ...
- C++ const用法小结 (欢迎大家拍砖)
C++const 关键字小结 const 是constant的缩写,本意是不变的,不易改变的意思. const 在C++中是用来修饰内置类型变量,自定义对象,成员函数,返回值,函数参数. 一.cons ...
- Silverlight浮动窗体 floatablewindow 非模态对话框
1.http://www.cnblogs.com/yinxiangpei/articles/2613913.html 说明:Silverlight的ChildWindow组件给我们的开发带来了便利,比 ...
- SQLServer数据库表中将指定列分组转一行
不说明,直接看代码: --1. 创建表,添加测试数据 CREATE TABLE #test(code varchar(50), [values] varchar(10)) INSERT #test S ...
- 一个JS的日期格式化算法示例
一个JS的日期格式化算法. 例子: <script> /** * Js日期格式化算法实例 * by www.jbxue.com */ function dateFormat(date, f ...
- JS判断鼠标从什么方向进入一个容器
偶然将想到的一个如何判断鼠标从哪个方向进入一个容器的问题.首先想到的是给容器的四个边添加几个块,然后看鼠标进入的时候哪个块先监听到鼠标事件.不过这样麻烦太多了.google了一下找到了一个不错的解决方 ...
- 如何使用js捕获css3动画
如何使用js捕获css3动画 css3动画功能强大,但是不像js,没有逐帧控制,但是可以通过js事件来确定任何动画的状态. 下面是一段css3动画代码: #anim.enable{ -webkit-a ...