【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同学在号节 ...
随机推荐
- ueditor 单独图片上传 转载
<body> <script type="text/javascript"> //这个是图片上传的,网上还有附件上传的 (function($) { var ...
- 杭电ACM2076--夹角有多大(题目已修改,注意读题)
杭电ACM2076--夹角有多大(题目已修改,注意读题) http://acm.hdu.edu.cn/showproblem.php?pid=2076 思路很简单.直接贴代码.过程分析有点耗时间. / ...
- 济南学习 Day 4 T1 am
完美的序列(sequence)Time Limit:1000ms Memory Limit:64MB题目描述LYK 认为一个完美的序列要满足这样的条件:对于任意两个位置上的数都不相同.然而并不是所有的 ...
- Netfilter深度解剖
在网络上发现这个Netfilter写的很好的系列文章,为了便于后期寻找,特此标注下博客地址,感谢大大神提供. ---------------------------分割线开始---- ...
- PHP合并数组保留key值
PHP合并数组,键值不变 尝试了好几个合并数组的函数, 但是都是把key值重置, 导致key值丢失(因为key值是要用到的) 大大说, 最好用数组的相关函数, 网上随意找了下, 还是没找到. 因为 ...
- Eclispe使用Maven添加官方库的jar包
先到百度或google搜索maven仓库,在仓库中搜索需要的jar包,如poi.jar. 搜索到之后找到需要的jar包,找到这里
- 方便实用的jQuery checkbox复选框全选功能
// 主复选框 <input type="checkbox" id="ck" name="ckAll">// 子复选框项 < ...
- Windows下MySQLroot密码破解
Win下MySQL修改root密码的多种方法 ##win2003mysql的密码破解 方法1: 用SET PASSWORD命令 mysql -u root mysql> SET PA ...
- PHP获取时间日期的多种方法
分享下PHP获取时间日期的多种方法. <?php echo "今天:".date("Y-m-d")."<br>"; ...
- ThoughtWorks FizzBuzzWhizz 代码实现
当时拉钩网ThoughtWorks出了一道面试题(https://www.jinshuju.net/f/EGQL3D),本人用PHP实现了一下,当时忘记了把代码分享出来,今天特来补上. FizzBuz ...